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 |
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; |
31 | PrintedType(const char *Type) : Type(Type) {} |
32 | 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(args: LHS.Type, args: LHS.AKA) == std::tie(args: RHS.Type, args: RHS.AKA); |
128 | } |
129 | |
130 | inline bool operator==(const HoverInfo::PassType &LHS, |
131 | const HoverInfo::PassType &RHS) { |
132 | return std::tie(args: LHS.PassBy, args: LHS.Converted) == |
133 | std::tie(args: RHS.PassBy, args: 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(args: LHS.Type, args: LHS.Name, args: LHS.Default) == |
146 | std::tie(args: RHS.Type, args: RHS.Name, args: 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 | |