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