1765b1250SSam McCall //===--- Hover.h - Information about code at the cursor location -*- C++-*-===// 2765b1250SSam McCall // 3765b1250SSam McCall // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4765b1250SSam McCall // See https://llvm.org/LICENSE.txt for license information. 5765b1250SSam McCall // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6765b1250SSam McCall // 7765b1250SSam McCall //===----------------------------------------------------------------------===// 8765b1250SSam McCall 9765b1250SSam McCall #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_HOVER_H 10765b1250SSam McCall #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_HOVER_H 11765b1250SSam McCall 12765b1250SSam McCall #include "ParsedAST.h" 13765b1250SSam McCall #include "Protocol.h" 14fa1f4cf8SSam McCall #include "support/Markup.h" 15c5adbac9SKadir Cetinkaya #include "clang/Index/IndexSymbol.h" 1671f55735SKazu Hirata #include <optional> 172bececb8SViktoriia Bakalova #include <string> 18655baae2SViktoriia Bakalova #include <vector> 19765b1250SSam McCall 20765b1250SSam McCall namespace clang { 21765b1250SSam McCall namespace clangd { 22765b1250SSam McCall 23765b1250SSam McCall /// Contains detailed information about a Symbol. Especially useful when 24765b1250SSam McCall /// generating hover responses. It can be rendered as a hover panel, or 25765b1250SSam McCall /// embedding clients can use the structured information to provide their own 26765b1250SSam McCall /// UI. 27765b1250SSam McCall struct HoverInfo { 28ec64d103Slh123 /// Contains pretty-printed type and desugared type 29ec64d103Slh123 struct PrintedType { 30ec64d103Slh123 PrintedType() = default; PrintedTypeHoverInfo::PrintedType31ec64d103Slh123 PrintedType(const char *Type) : Type(Type) {} PrintedTypeHoverInfo::PrintedType32ec64d103Slh123 PrintedType(const char *Type, const char *AKAType) 33ec64d103Slh123 : Type(Type), AKA(AKAType) {} 34ec64d103Slh123 35ec64d103Slh123 /// Pretty-printed type 36ec64d103Slh123 std::string Type; 37ec64d103Slh123 /// Desugared type 38f71ffd3bSKazu Hirata std::optional<std::string> AKA; 39ec64d103Slh123 }; 40ec64d103Slh123 41765b1250SSam McCall /// Represents parameters of a function, a template or a macro. 42765b1250SSam McCall /// For example: 43765b1250SSam McCall /// - void foo(ParamType Name = DefaultValue) 44765b1250SSam McCall /// - #define FOO(Name) 45765b1250SSam McCall /// - template <ParamType Name = DefaultType> class Foo {}; 46765b1250SSam McCall struct Param { 47ec64d103Slh123 /// The printable parameter type, e.g. "int", or "typename" (in 48c824db46SKazu Hirata /// TemplateParameters), might be std::nullopt for macro parameters. 49f71ffd3bSKazu Hirata std::optional<PrintedType> Type; 50c824db46SKazu Hirata /// std::nullopt for unnamed parameters. 518310bec5SFangrui Song std::optional<std::string> Name; 52c824db46SKazu Hirata /// std::nullopt if no default is provided. 53f71ffd3bSKazu Hirata std::optional<std::string> Default; 54765b1250SSam McCall }; 55765b1250SSam McCall 56765b1250SSam McCall /// For a variable named Bar, declared in clang::clangd::Foo::getFoo the 57765b1250SSam McCall /// following fields will hold: 58765b1250SSam McCall /// - NamespaceScope: clang::clangd:: 59765b1250SSam McCall /// - LocalScope: Foo::getFoo:: 60765b1250SSam McCall /// - Name: Bar 61765b1250SSam McCall 62765b1250SSam McCall /// Scopes might be None in cases where they don't make sense, e.g. macros and 63765b1250SSam McCall /// auto/decltype. 64765b1250SSam McCall /// Contains all of the enclosing namespaces, empty string means global 65765b1250SSam McCall /// namespace. 66f71ffd3bSKazu Hirata std::optional<std::string> NamespaceScope; 67765b1250SSam McCall /// Remaining named contexts in symbol's qualified name, empty string means 68765b1250SSam McCall /// symbol is not local. 69765b1250SSam McCall std::string LocalScope; 70765b1250SSam McCall /// Name of the symbol, does not contain any "::". 71765b1250SSam McCall std::string Name; 722bececb8SViktoriia Bakalova /// Header providing the symbol (best match). Contains ""<>. 732bececb8SViktoriia Bakalova std::string Provider; 74f71ffd3bSKazu Hirata std::optional<Range> SymRange; 75c5adbac9SKadir Cetinkaya index::SymbolKind Kind = index::SymbolKind::Unknown; 76765b1250SSam McCall std::string Documentation; 77765b1250SSam McCall /// Source code containing the definition of the symbol. 78765b1250SSam McCall std::string Definition; 79f9c8602bSChristian Kandeler const char *DefinitionLanguage = "cpp"; 806407aa9dSDaniel Martín /// Access specifier for declarations inside class/struct/unions, empty for 816407aa9dSDaniel Martín /// others. 826407aa9dSDaniel Martín std::string AccessSpecifier; 83ec64d103Slh123 /// Printable variable type. 84765b1250SSam McCall /// Set only for variables. 85f71ffd3bSKazu Hirata std::optional<PrintedType> Type; 86dd5571d5SKazuaki Ishizaki /// Set for functions and lambdas. 87f71ffd3bSKazu Hirata std::optional<PrintedType> ReturnType; 88765b1250SSam McCall /// Set for functions, lambdas and macros with parameters. 89f71ffd3bSKazu Hirata std::optional<std::vector<Param>> Parameters; 90765b1250SSam McCall /// Set for all templates(function, class, variable). 91f71ffd3bSKazu Hirata std::optional<std::vector<Param>> TemplateParameters; 92765b1250SSam McCall /// Contains the evaluated value of the symbol if available. 93f71ffd3bSKazu Hirata std::optional<std::string> Value; 944cb5e436SSR_team /// Contains the bit-size of fields and types where it's interesting. 95f71ffd3bSKazu Hirata std::optional<uint64_t> Size; 96c1a00b89SSam McCall /// Contains the offset of fields within the enclosing class. 97f71ffd3bSKazu Hirata std::optional<uint64_t> Offset; 98b447445eSSam McCall /// Contains the padding following a field within the enclosing class. 99f71ffd3bSKazu Hirata std::optional<uint64_t> Padding; 100*c3008842SSR_team /// Contains the alignment of fields and types where it's interesting. 101*c3008842SSR_team std::optional<uint64_t> Align; 1025c46fefdSAdam Czachorowski // Set when symbol is inside function call. Contains information extracted 1035c46fefdSAdam Czachorowski // from the callee definition about the argument this is passed as. 104f71ffd3bSKazu Hirata std::optional<Param> CalleeArgInfo; 1055c46fefdSAdam Czachorowski struct PassType { 1065c46fefdSAdam Czachorowski // How the variable is passed to callee. 1075c46fefdSAdam Czachorowski enum PassMode { Ref, ConstRef, Value }; 1085c46fefdSAdam Czachorowski PassMode PassBy = Ref; 1095c46fefdSAdam Czachorowski // True if type conversion happened. This includes calls to implicit 1105c46fefdSAdam Czachorowski // constructor, as well as built-in type conversions. Casting to base class 1115c46fefdSAdam Czachorowski // is not considered conversion. 1125c46fefdSAdam Czachorowski bool Converted = false; 1135c46fefdSAdam Czachorowski }; 1145c46fefdSAdam Czachorowski // Set only if CalleeArgInfo is set. 115f71ffd3bSKazu Hirata std::optional<PassType> CallPassType; 116655baae2SViktoriia Bakalova // Filled when hovering over the #include line. Contains the names of symbols 117655baae2SViktoriia Bakalova // from a #include'd file that are used in the main file, sorted in 118655baae2SViktoriia Bakalova // alphabetical order. 119655baae2SViktoriia Bakalova std::vector<std::string> UsedSymbolNames; 120765b1250SSam McCall 121765b1250SSam McCall /// Produce a user-readable information. 122597c6b65SKadir Cetinkaya markup::Document present() const; 123765b1250SSam McCall }; 124b194e7d6SLorenz Junglas 125ec64d103Slh123 inline bool operator==(const HoverInfo::PrintedType &LHS, 126ec64d103Slh123 const HoverInfo::PrintedType &RHS) { 127ec64d103Slh123 return std::tie(LHS.Type, LHS.AKA) == std::tie(RHS.Type, RHS.AKA); 128ec64d103Slh123 } 129ec64d103Slh123 1305c46fefdSAdam Czachorowski inline bool operator==(const HoverInfo::PassType &LHS, 1315c46fefdSAdam Czachorowski const HoverInfo::PassType &RHS) { 1325c46fefdSAdam Czachorowski return std::tie(LHS.PassBy, LHS.Converted) == 1335c46fefdSAdam Czachorowski std::tie(RHS.PassBy, RHS.Converted); 1345c46fefdSAdam Czachorowski } 1355c46fefdSAdam Czachorowski 136b194e7d6SLorenz Junglas // Try to infer structure of a documentation comment (e.g. line breaks). 137a3a27a7aSSam McCall // FIXME: move to another file so CodeComplete doesn't depend on Hover. 138b194e7d6SLorenz Junglas void parseDocumentation(llvm::StringRef Input, markup::Document &Output); 139b194e7d6SLorenz Junglas 140ec64d103Slh123 llvm::raw_ostream &operator<<(llvm::raw_ostream &, 141ec64d103Slh123 const HoverInfo::PrintedType &); 142765b1250SSam McCall llvm::raw_ostream &operator<<(llvm::raw_ostream &, const HoverInfo::Param &); 143765b1250SSam McCall inline bool operator==(const HoverInfo::Param &LHS, 144765b1250SSam McCall const HoverInfo::Param &RHS) { 145765b1250SSam McCall return std::tie(LHS.Type, LHS.Name, LHS.Default) == 146765b1250SSam McCall std::tie(RHS.Type, RHS.Name, RHS.Default); 147765b1250SSam McCall } 148765b1250SSam McCall 149765b1250SSam McCall /// Get the hover information when hovering at \p Pos. 1501da3a795SFangrui Song std::optional<HoverInfo> getHover(ParsedAST &AST, Position Pos, 1519415fbbbSSimon Pilgrim const format::FormatStyle &Style, 152765b1250SSam McCall const SymbolIndex *Index); 153765b1250SSam McCall 154765b1250SSam McCall } // namespace clangd 155765b1250SSam McCall } // namespace clang 156765b1250SSam McCall 157765b1250SSam McCall #endif 158