xref: /llvm-project/clang-tools-extra/clangd/Hover.h (revision c3008842bf19e3a00db1f8adbd95d43f71b4f09f)
1765b1250SSam McCall //===--- Hover.h - Information about code at the cursor location -*- C++-*-===//
2765b1250SSam McCall //
3765b1250SSam McCall // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4765b1250SSam McCall // See https://llvm.org/LICENSE.txt for license information.
5765b1250SSam McCall // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6765b1250SSam McCall //
7765b1250SSam McCall //===----------------------------------------------------------------------===//
8765b1250SSam McCall 
9765b1250SSam McCall #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_HOVER_H
10765b1250SSam McCall #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_HOVER_H
11765b1250SSam McCall 
12765b1250SSam McCall #include "ParsedAST.h"
13765b1250SSam McCall #include "Protocol.h"
14fa1f4cf8SSam McCall #include "support/Markup.h"
15c5adbac9SKadir Cetinkaya #include "clang/Index/IndexSymbol.h"
1671f55735SKazu Hirata #include <optional>
172bececb8SViktoriia Bakalova #include <string>
18655baae2SViktoriia Bakalova #include <vector>
19765b1250SSam McCall 
20765b1250SSam McCall namespace clang {
21765b1250SSam McCall namespace clangd {
22765b1250SSam McCall 
23765b1250SSam McCall /// Contains detailed information about a Symbol. Especially useful when
24765b1250SSam McCall /// generating hover responses. It can be rendered as a hover panel, or
25765b1250SSam McCall /// embedding clients can use the structured information to provide their own
26765b1250SSam McCall /// UI.
27765b1250SSam McCall struct HoverInfo {
28ec64d103Slh123   /// Contains pretty-printed type and desugared type
29ec64d103Slh123   struct PrintedType {
30ec64d103Slh123     PrintedType() = default;
PrintedTypeHoverInfo::PrintedType31ec64d103Slh123     PrintedType(const char *Type) : Type(Type) {}
PrintedTypeHoverInfo::PrintedType32ec64d103Slh123     PrintedType(const char *Type, const char *AKAType)
33ec64d103Slh123         : Type(Type), AKA(AKAType) {}
34ec64d103Slh123 
35ec64d103Slh123     /// Pretty-printed type
36ec64d103Slh123     std::string Type;
37ec64d103Slh123     /// Desugared type
38f71ffd3bSKazu Hirata     std::optional<std::string> AKA;
39ec64d103Slh123   };
40ec64d103Slh123 
41765b1250SSam McCall   /// Represents parameters of a function, a template or a macro.
42765b1250SSam McCall   /// For example:
43765b1250SSam McCall   /// - void foo(ParamType Name = DefaultValue)
44765b1250SSam McCall   /// - #define FOO(Name)
45765b1250SSam McCall   /// - template <ParamType Name = DefaultType> class Foo {};
46765b1250SSam McCall   struct Param {
47ec64d103Slh123     /// The printable parameter type, e.g. "int", or "typename" (in
48c824db46SKazu Hirata     /// TemplateParameters), might be std::nullopt for macro parameters.
49f71ffd3bSKazu Hirata     std::optional<PrintedType> Type;
50c824db46SKazu Hirata     /// std::nullopt for unnamed parameters.
518310bec5SFangrui Song     std::optional<std::string> Name;
52c824db46SKazu Hirata     /// std::nullopt if no default is provided.
53f71ffd3bSKazu Hirata     std::optional<std::string> Default;
54765b1250SSam McCall   };
55765b1250SSam McCall 
56765b1250SSam McCall   /// For a variable named Bar, declared in clang::clangd::Foo::getFoo the
57765b1250SSam McCall   /// following fields will hold:
58765b1250SSam McCall   /// - NamespaceScope: clang::clangd::
59765b1250SSam McCall   /// - LocalScope: Foo::getFoo::
60765b1250SSam McCall   /// - Name: Bar
61765b1250SSam McCall 
62765b1250SSam McCall   /// Scopes might be None in cases where they don't make sense, e.g. macros and
63765b1250SSam McCall   /// auto/decltype.
64765b1250SSam McCall   /// Contains all of the enclosing namespaces, empty string means global
65765b1250SSam McCall   /// namespace.
66f71ffd3bSKazu Hirata   std::optional<std::string> NamespaceScope;
67765b1250SSam McCall   /// Remaining named contexts in symbol's qualified name, empty string means
68765b1250SSam McCall   /// symbol is not local.
69765b1250SSam McCall   std::string LocalScope;
70765b1250SSam McCall   /// Name of the symbol, does not contain any "::".
71765b1250SSam McCall   std::string Name;
722bececb8SViktoriia Bakalova   /// Header providing the symbol (best match). Contains ""<>.
732bececb8SViktoriia Bakalova   std::string Provider;
74f71ffd3bSKazu Hirata   std::optional<Range> SymRange;
75c5adbac9SKadir Cetinkaya   index::SymbolKind Kind = index::SymbolKind::Unknown;
76765b1250SSam McCall   std::string Documentation;
77765b1250SSam McCall   /// Source code containing the definition of the symbol.
78765b1250SSam McCall   std::string Definition;
79f9c8602bSChristian Kandeler   const char *DefinitionLanguage = "cpp";
806407aa9dSDaniel Martín   /// Access specifier for declarations inside class/struct/unions, empty for
816407aa9dSDaniel Martín   /// others.
826407aa9dSDaniel Martín   std::string AccessSpecifier;
83ec64d103Slh123   /// Printable variable type.
84765b1250SSam McCall   /// Set only for variables.
85f71ffd3bSKazu Hirata   std::optional<PrintedType> Type;
86dd5571d5SKazuaki Ishizaki   /// Set for functions and lambdas.
87f71ffd3bSKazu Hirata   std::optional<PrintedType> ReturnType;
88765b1250SSam McCall   /// Set for functions, lambdas and macros with parameters.
89f71ffd3bSKazu Hirata   std::optional<std::vector<Param>> Parameters;
90765b1250SSam McCall   /// Set for all templates(function, class, variable).
91f71ffd3bSKazu Hirata   std::optional<std::vector<Param>> TemplateParameters;
92765b1250SSam McCall   /// Contains the evaluated value of the symbol if available.
93f71ffd3bSKazu Hirata   std::optional<std::string> Value;
944cb5e436SSR_team   /// Contains the bit-size of fields and types where it's interesting.
95f71ffd3bSKazu Hirata   std::optional<uint64_t> Size;
96c1a00b89SSam McCall   /// Contains the offset of fields within the enclosing class.
97f71ffd3bSKazu Hirata   std::optional<uint64_t> Offset;
98b447445eSSam McCall   /// Contains the padding following a field within the enclosing class.
99f71ffd3bSKazu Hirata   std::optional<uint64_t> Padding;
100*c3008842SSR_team   /// Contains the alignment of fields and types where it's interesting.
101*c3008842SSR_team   std::optional<uint64_t> Align;
1025c46fefdSAdam Czachorowski   // Set when symbol is inside function call. Contains information extracted
1035c46fefdSAdam Czachorowski   // from the callee definition about the argument this is passed as.
104f71ffd3bSKazu Hirata   std::optional<Param> CalleeArgInfo;
1055c46fefdSAdam Czachorowski   struct PassType {
1065c46fefdSAdam Czachorowski     // How the variable is passed to callee.
1075c46fefdSAdam Czachorowski     enum PassMode { Ref, ConstRef, Value };
1085c46fefdSAdam Czachorowski     PassMode PassBy = Ref;
1095c46fefdSAdam Czachorowski     // True if type conversion happened. This includes calls to implicit
1105c46fefdSAdam Czachorowski     // constructor, as well as built-in type conversions. Casting to base class
1115c46fefdSAdam Czachorowski     // is not considered conversion.
1125c46fefdSAdam Czachorowski     bool Converted = false;
1135c46fefdSAdam Czachorowski   };
1145c46fefdSAdam Czachorowski   // Set only if CalleeArgInfo is set.
115f71ffd3bSKazu Hirata   std::optional<PassType> CallPassType;
116655baae2SViktoriia Bakalova   // Filled when hovering over the #include line. Contains the names of symbols
117655baae2SViktoriia Bakalova   // from a #include'd file that are used in the main file, sorted in
118655baae2SViktoriia Bakalova   // alphabetical order.
119655baae2SViktoriia Bakalova   std::vector<std::string> UsedSymbolNames;
120765b1250SSam McCall 
121765b1250SSam McCall   /// Produce a user-readable information.
122597c6b65SKadir Cetinkaya   markup::Document present() const;
123765b1250SSam McCall };
124b194e7d6SLorenz Junglas 
125ec64d103Slh123 inline bool operator==(const HoverInfo::PrintedType &LHS,
126ec64d103Slh123                        const HoverInfo::PrintedType &RHS) {
127ec64d103Slh123   return std::tie(LHS.Type, LHS.AKA) == std::tie(RHS.Type, RHS.AKA);
128ec64d103Slh123 }
129ec64d103Slh123 
1305c46fefdSAdam Czachorowski inline bool operator==(const HoverInfo::PassType &LHS,
1315c46fefdSAdam Czachorowski                        const HoverInfo::PassType &RHS) {
1325c46fefdSAdam Czachorowski   return std::tie(LHS.PassBy, LHS.Converted) ==
1335c46fefdSAdam Czachorowski          std::tie(RHS.PassBy, RHS.Converted);
1345c46fefdSAdam Czachorowski }
1355c46fefdSAdam Czachorowski 
136b194e7d6SLorenz Junglas // Try to infer structure of a documentation comment (e.g. line breaks).
137a3a27a7aSSam McCall // FIXME: move to another file so CodeComplete doesn't depend on Hover.
138b194e7d6SLorenz Junglas void parseDocumentation(llvm::StringRef Input, markup::Document &Output);
139b194e7d6SLorenz Junglas 
140ec64d103Slh123 llvm::raw_ostream &operator<<(llvm::raw_ostream &,
141ec64d103Slh123                               const HoverInfo::PrintedType &);
142765b1250SSam McCall llvm::raw_ostream &operator<<(llvm::raw_ostream &, const HoverInfo::Param &);
143765b1250SSam McCall inline bool operator==(const HoverInfo::Param &LHS,
144765b1250SSam McCall                        const HoverInfo::Param &RHS) {
145765b1250SSam McCall   return std::tie(LHS.Type, LHS.Name, LHS.Default) ==
146765b1250SSam McCall          std::tie(RHS.Type, RHS.Name, RHS.Default);
147765b1250SSam McCall }
148765b1250SSam McCall 
149765b1250SSam McCall /// Get the hover information when hovering at \p Pos.
1501da3a795SFangrui Song std::optional<HoverInfo> getHover(ParsedAST &AST, Position Pos,
1519415fbbbSSimon Pilgrim                                   const format::FormatStyle &Style,
152765b1250SSam McCall                                   const SymbolIndex *Index);
153765b1250SSam McCall 
154765b1250SSam McCall } // namespace clangd
155765b1250SSam McCall } // namespace clang
156765b1250SSam McCall 
157765b1250SSam McCall #endif
158