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   const char *DefinitionLanguage = "cpp";
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   /// Contains the padding following a field within the enclosing class.
81   llvm::Optional<uint64_t> Padding;
82   // Set when symbol is inside function call. Contains information extracted
83   // from the callee definition about the argument this is passed as.
84   llvm::Optional<Param> CalleeArgInfo;
85   struct PassType {
86     // How the variable is passed to callee.
87     enum PassMode { Ref, ConstRef, Value };
88     PassMode PassBy = Ref;
89     // True if type conversion happened. This includes calls to implicit
90     // constructor, as well as built-in type conversions. Casting to base class
91     // is not considered conversion.
92     bool Converted = false;
93   };
94   // Set only if CalleeArgInfo is set.
95   llvm::Optional<PassType> CallPassType;
96 
97   /// Produce a user-readable information.
98   markup::Document present() const;
99 };
100 
101 inline bool operator==(const HoverInfo::PassType &LHS,
102                        const HoverInfo::PassType &RHS) {
103   return std::tie(LHS.PassBy, LHS.Converted) ==
104          std::tie(RHS.PassBy, RHS.Converted);
105 }
106 
107 // Try to infer structure of a documentation comment (e.g. line breaks).
108 // FIXME: move to another file so CodeComplete doesn't depend on Hover.
109 void parseDocumentation(llvm::StringRef Input, markup::Document &Output);
110 
111 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const HoverInfo::Param &);
112 inline bool operator==(const HoverInfo::Param &LHS,
113                        const HoverInfo::Param &RHS) {
114   return std::tie(LHS.Type, LHS.Name, LHS.Default) ==
115          std::tie(RHS.Type, RHS.Name, RHS.Default);
116 }
117 
118 /// Get the hover information when hovering at \p Pos.
119 llvm::Optional<HoverInfo> getHover(ParsedAST &AST, Position Pos,
120                                    format::FormatStyle Style,
121                                    const SymbolIndex *Index);
122 
123 } // namespace clangd
124 } // namespace clang
125 
126 #endif
127