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