xref: /llvm-project/clang-tools-extra/clangd/Hover.h (revision c3008842bf19e3a00db1f8adbd95d43f71b4f09f)
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