1 //===--- Hover.h - Information about code at the cursor location -*- C++-*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_HOVER_H 10 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_HOVER_H 11 12 #include "ParsedAST.h" 13 #include "Protocol.h" 14 #include "support/Markup.h" 15 #include "clang/Index/IndexSymbol.h" 16 #include <optional> 17 #include <string> 18 #include <vector> 19 20 namespace clang { 21 namespace clangd { 22 23 /// Contains detailed information about a Symbol. Especially useful when 24 /// generating hover responses. It can be rendered as a hover panel, or 25 /// embedding clients can use the structured information to provide their own 26 /// UI. 27 struct HoverInfo { 28 /// Contains pretty-printed type and desugared type 29 struct PrintedType { 30 PrintedType() = default; PrintedTypeHoverInfo::PrintedType31 PrintedType(const char *Type) : Type(Type) {} PrintedTypeHoverInfo::PrintedType32 PrintedType(const char *Type, const char *AKAType) 33 : Type(Type), AKA(AKAType) {} 34 35 /// Pretty-printed type 36 std::string Type; 37 /// Desugared type 38 std::optional<std::string> AKA; 39 }; 40 41 /// Represents parameters of a function, a template or a macro. 42 /// For example: 43 /// - void foo(ParamType Name = DefaultValue) 44 /// - #define FOO(Name) 45 /// - template <ParamType Name = DefaultType> class Foo {}; 46 struct Param { 47 /// The printable parameter type, e.g. "int", or "typename" (in 48 /// TemplateParameters), might be std::nullopt for macro parameters. 49 std::optional<PrintedType> Type; 50 /// std::nullopt for unnamed parameters. 51 std::optional<std::string> Name; 52 /// std::nullopt if no default is provided. 53 std::optional<std::string> Default; 54 }; 55 56 /// For a variable named Bar, declared in clang::clangd::Foo::getFoo the 57 /// following fields will hold: 58 /// - NamespaceScope: clang::clangd:: 59 /// - LocalScope: Foo::getFoo:: 60 /// - Name: Bar 61 62 /// Scopes might be None in cases where they don't make sense, e.g. macros and 63 /// auto/decltype. 64 /// Contains all of the enclosing namespaces, empty string means global 65 /// namespace. 66 std::optional<std::string> NamespaceScope; 67 /// Remaining named contexts in symbol's qualified name, empty string means 68 /// symbol is not local. 69 std::string LocalScope; 70 /// Name of the symbol, does not contain any "::". 71 std::string Name; 72 /// Header providing the symbol (best match). Contains ""<>. 73 std::string Provider; 74 std::optional<Range> SymRange; 75 index::SymbolKind Kind = index::SymbolKind::Unknown; 76 std::string Documentation; 77 /// Source code containing the definition of the symbol. 78 std::string Definition; 79 const char *DefinitionLanguage = "cpp"; 80 /// Access specifier for declarations inside class/struct/unions, empty for 81 /// others. 82 std::string AccessSpecifier; 83 /// Printable variable type. 84 /// Set only for variables. 85 std::optional<PrintedType> Type; 86 /// Set for functions and lambdas. 87 std::optional<PrintedType> ReturnType; 88 /// Set for functions, lambdas and macros with parameters. 89 std::optional<std::vector<Param>> Parameters; 90 /// Set for all templates(function, class, variable). 91 std::optional<std::vector<Param>> TemplateParameters; 92 /// Contains the evaluated value of the symbol if available. 93 std::optional<std::string> Value; 94 /// Contains the bit-size of fields and types where it's interesting. 95 std::optional<uint64_t> Size; 96 /// Contains the offset of fields within the enclosing class. 97 std::optional<uint64_t> Offset; 98 /// Contains the padding following a field within the enclosing class. 99 std::optional<uint64_t> Padding; 100 /// Contains the alignment of fields and types where it's interesting. 101 std::optional<uint64_t> Align; 102 // Set when symbol is inside function call. Contains information extracted 103 // from the callee definition about the argument this is passed as. 104 std::optional<Param> CalleeArgInfo; 105 struct PassType { 106 // How the variable is passed to callee. 107 enum PassMode { Ref, ConstRef, Value }; 108 PassMode PassBy = Ref; 109 // True if type conversion happened. This includes calls to implicit 110 // constructor, as well as built-in type conversions. Casting to base class 111 // is not considered conversion. 112 bool Converted = false; 113 }; 114 // Set only if CalleeArgInfo is set. 115 std::optional<PassType> CallPassType; 116 // Filled when hovering over the #include line. Contains the names of symbols 117 // from a #include'd file that are used in the main file, sorted in 118 // alphabetical order. 119 std::vector<std::string> UsedSymbolNames; 120 121 /// Produce a user-readable information. 122 markup::Document present() const; 123 }; 124 125 inline bool operator==(const HoverInfo::PrintedType &LHS, 126 const HoverInfo::PrintedType &RHS) { 127 return std::tie(LHS.Type, LHS.AKA) == std::tie(RHS.Type, RHS.AKA); 128 } 129 130 inline bool operator==(const HoverInfo::PassType &LHS, 131 const HoverInfo::PassType &RHS) { 132 return std::tie(LHS.PassBy, LHS.Converted) == 133 std::tie(RHS.PassBy, RHS.Converted); 134 } 135 136 // Try to infer structure of a documentation comment (e.g. line breaks). 137 // FIXME: move to another file so CodeComplete doesn't depend on Hover. 138 void parseDocumentation(llvm::StringRef Input, markup::Document &Output); 139 140 llvm::raw_ostream &operator<<(llvm::raw_ostream &, 141 const HoverInfo::PrintedType &); 142 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const HoverInfo::Param &); 143 inline bool operator==(const HoverInfo::Param &LHS, 144 const HoverInfo::Param &RHS) { 145 return std::tie(LHS.Type, LHS.Name, LHS.Default) == 146 std::tie(RHS.Type, RHS.Name, RHS.Default); 147 } 148 149 /// Get the hover information when hovering at \p Pos. 150 std::optional<HoverInfo> getHover(ParsedAST &AST, Position Pos, 151 const format::FormatStyle &Style, 152 const SymbolIndex *Index); 153 154 } // namespace clangd 155 } // namespace clang 156 157 #endif 158