diff --git a/src/indexer.h b/src/indexer.h index 81aca123..e7c588cd 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -2,7 +2,6 @@ #include "clang_cursor.h" #include "clang_index.h" -#include "clang_symbol_kind.h" #include "clang_translation_unit.h" #include "clang_utils.h" #include "file_consumer.h" @@ -13,6 +12,7 @@ #include "performance.h" #include "position.h" #include "serializer.h" +#include "symbol.h" #include "utils.h" #include @@ -33,12 +33,6 @@ struct IndexType; struct IndexFunc; struct IndexVar; -// 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); -MAKE_ENUM_HASHABLE(SymbolKind); - using RawId = uint32_t; template diff --git a/src/language_server_api.cc b/src/language_server_api.cc index 88215d6f..0f4898c5 100644 --- a/src/language_server_api.cc +++ b/src/language_server_api.cc @@ -285,16 +285,25 @@ const lsPosition lsPosition::kZeroPosition = lsPosition(); lsRange::lsRange() {} lsRange::lsRange(lsPosition start, lsPosition end) : start(start), end(end) {} -bool lsRange::operator==(const lsRange& other) const { - return start == other.start && end == other.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& other) const { - return uri == other.uri && range == other.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) { diff --git a/src/language_server_api.h b/src/language_server_api.h index bb730b1f..ed98142c 100644 --- a/src/language_server_api.h +++ b/src/language_server_api.h @@ -159,6 +159,7 @@ struct lsRange { lsRange(lsPosition start, lsPosition end); bool operator==(const lsRange& other) const; + bool operator<(const lsRange& other) const; lsPosition start; lsPosition end; @@ -171,6 +172,7 @@ struct lsLocation { lsLocation(lsDocumentUri uri, lsRange range); bool operator==(const lsLocation& other) const; + bool operator<(const lsLocation& o) const; lsDocumentUri uri; lsRange range; @@ -184,36 +186,6 @@ struct lsLocationEx : lsLocation { }; MAKE_REFLECT_STRUCT(lsLocationEx, uri, range, containerName); -enum class lsSymbolKind : int { - File = 1, - Module = 2, - Namespace = 3, - Package = 4, - Class = 5, - Method = 6, - Property = 7, - Field = 8, - Constructor = 9, - Enum = 10, - Interface = 11, - Function = 12, - Variable = 13, - Constant = 14, - String = 15, - Number = 16, - Boolean = 17, - Array = 18 -}; -MAKE_REFLECT_TYPE_PROXY(lsSymbolKind); - -struct lsSymbolInformation { - std::string_view name; - lsSymbolKind kind; - lsLocation location; - std::string_view containerName; -}; -MAKE_REFLECT_STRUCT(lsSymbolInformation, name, kind, location, containerName); - template struct lsCommand { // Title of the command (ie, 'save') @@ -456,17 +428,6 @@ struct lsWorkspaceEdit { }; MAKE_REFLECT_STRUCT(lsWorkspaceEdit, documentChanges); -// 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); - struct lsFormattingOptions { // Size of a tab in spaces. int tabSize; @@ -475,18 +436,6 @@ struct lsFormattingOptions { }; MAKE_REFLECT_STRUCT(lsFormattingOptions, tabSize, insertSpaces); -// 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; -}; -MAKE_REFLECT_STRUCT(lsDocumentHighlight, range, kind); - enum class lsDiagnosticSeverity { // Reports an error. Error = 1, diff --git a/src/messages/text_document_highlight.cc b/src/messages/text_document_document_highlight.cc similarity index 86% rename from src/messages/text_document_highlight.cc rename to src/messages/text_document_document_highlight.cc index 5babbc20..2450acab 100644 --- a/src/messages/text_document_highlight.cc +++ b/src/messages/text_document_document_highlight.cc @@ -1,6 +1,7 @@ #include "message_handler.h" #include "query_utils.h" #include "queue_manager.h" +#include "symbol.h" namespace { struct Ipc_TextDocumentDocumentHighlight @@ -50,8 +51,14 @@ struct TextDocumentDocumentHighlightHandler continue; lsDocumentHighlight highlight; - highlight.kind = lsDocumentHighlightKind::Text; highlight.range = ls_location->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; diff --git a/src/query_utils.cc b/src/query_utils.cc index 2888bd45..44155241 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -426,19 +426,16 @@ std::vector GetLsLocations( QueryDatabase* db, WorkingFiles* working_files, const std::vector& uses) { - std::unordered_set unique_locations; + std::vector ret; for (Use use : uses) { optional location = GetLsLocation(db, working_files, use); - if (!location) - continue; - unique_locations.insert(*location); + if (location) + ret.push_back(*location); } - - std::vector result; - result.reserve(unique_locations.size()); - result.assign(unique_locations.begin(), unique_locations.end()); - return result; + std::sort(ret.begin(), ret.end()); + ret.erase(std::unique(ret.begin(), ret.end()), ret.end()); + return ret; } // Returns a symbol. The symbol will have *NOT* have a location assigned. @@ -491,14 +488,15 @@ optional GetSymbolInfo(QueryDatabase* db, else info.name = func.def->detailed_name; info.containerName = func.def->detailed_name; - info.kind = lsSymbolKind::Function; - - if (func.def->declaring_type) { - QueryType& container = db->types[func.def->declaring_type->id]; - if (container.def) + switch (func.def->kind) { + default: + info.kind = lsSymbolKind::Function; + break; + case ClangSymbolKind::InstanceMethod: + case ClangSymbolKind::StaticMethod: info.kind = lsSymbolKind::Method; + break; } - return info; } case SymbolKind::Var: { diff --git a/src/clang_symbol_kind.h b/src/symbol.h similarity index 51% rename from src/clang_symbol_kind.h rename to src/symbol.h index 3138f615..e8e906a3 100644 --- a/src/clang_symbol_kind.h +++ b/src/symbol.h @@ -2,7 +2,11 @@ #include "serializer.h" -#include +// 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); +MAKE_ENUM_HASHABLE(SymbolKind); // TODO Rename query.h:SymbolKind to another name // clang/Index/IndexSymbol.h clang::index::SymbolKind @@ -88,3 +92,59 @@ inline uint16_t operator&(Role lhs, Role rhs) { 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; + + // cquery extension + Role role = Role::None; +}; +MAKE_REFLECT_STRUCT(lsDocumentHighlight, range, kind, role); + +enum class lsSymbolKind : int { + File = 1, + Module = 2, + Namespace = 3, + Package = 4, + Class = 5, + Method = 6, + Property = 7, + Field = 8, + Constructor = 9, + Enum = 10, + Interface = 11, + Function = 12, + Variable = 13, + Constant = 14, + String = 15, + Number = 16, + Boolean = 17, + Array = 18 +}; +MAKE_REFLECT_TYPE_PROXY(lsSymbolKind); + +struct lsSymbolInformation { + std::string_view name; + lsSymbolKind kind; + lsLocation location; + std::string_view containerName; +}; +MAKE_REFLECT_STRUCT(lsSymbolInformation, name, kind, location, containerName);