1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
|
//===--- Hover.h - Information about code at the cursor location -*- C++-*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_HOVER_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_HOVER_H
#include "ParsedAST.h"
#include "Protocol.h"
#include "support/Markup.h"
#include "clang/Index/IndexSymbol.h"
namespace clang {
namespace clangd {
/// Contains detailed information about a Symbol. Especially useful when
/// generating hover responses. It can be rendered as a hover panel, or
/// embedding clients can use the structured information to provide their own
/// UI.
struct HoverInfo {
/// Contains pretty-printed type and desugared type
struct PrintedType {
PrintedType() = default;
PrintedType(const char *Type) : Type(Type) {}
PrintedType(const char *Type, const char *AKAType)
: Type(Type), AKA(AKAType) {}
/// Pretty-printed type
std::string Type;
/// Desugared type
llvm::Optional<std::string> AKA;
};
/// Represents parameters of a function, a template or a macro.
/// For example:
/// - void foo(ParamType Name = DefaultValue)
/// - #define FOO(Name)
/// - template <ParamType Name = DefaultType> class Foo {};
struct Param {
/// The printable parameter type, e.g. "int", or "typename" (in
/// TemplateParameters), might be None for macro parameters.
llvm::Optional<PrintedType> Type;
/// None for unnamed parameters.
llvm::Optional<std::string> Name;
/// None if no default is provided.
llvm::Optional<std::string> Default;
};
/// For a variable named Bar, declared in clang::clangd::Foo::getFoo the
/// following fields will hold:
/// - NamespaceScope: clang::clangd::
/// - LocalScope: Foo::getFoo::
/// - Name: Bar
/// Scopes might be None in cases where they don't make sense, e.g. macros and
/// auto/decltype.
/// Contains all of the enclosing namespaces, empty string means global
/// namespace.
llvm::Optional<std::string> NamespaceScope;
/// Remaining named contexts in symbol's qualified name, empty string means
/// symbol is not local.
std::string LocalScope;
/// Name of the symbol, does not contain any "::".
std::string Name;
llvm::Optional<Range> SymRange;
index::SymbolKind Kind = index::SymbolKind::Unknown;
std::string Documentation;
/// Source code containing the definition of the symbol.
std::string Definition;
const char *DefinitionLanguage = "cpp";
/// Access specifier for declarations inside class/struct/unions, empty for
/// others.
std::string AccessSpecifier;
/// Printable variable type.
/// Set only for variables.
llvm::Optional<PrintedType> Type;
/// Set for functions and lambdas.
llvm::Optional<PrintedType> ReturnType;
/// Set for functions, lambdas and macros with parameters.
llvm::Optional<std::vector<Param>> Parameters;
/// Set for all templates(function, class, variable).
llvm::Optional<std::vector<Param>> TemplateParameters;
/// Contains the evaluated value of the symbol if available.
llvm::Optional<std::string> Value;
/// Contains the byte-size of fields and types where it's interesting.
llvm::Optional<uint64_t> Size;
/// Contains the offset of fields within the enclosing class.
llvm::Optional<uint64_t> Offset;
/// Contains the padding following a field within the enclosing class.
llvm::Optional<uint64_t> Padding;
// Set when symbol is inside function call. Contains information extracted
// from the callee definition about the argument this is passed as.
llvm::Optional<Param> CalleeArgInfo;
struct PassType {
// How the variable is passed to callee.
enum PassMode { Ref, ConstRef, Value };
PassMode PassBy = Ref;
// True if type conversion happened. This includes calls to implicit
// constructor, as well as built-in type conversions. Casting to base class
// is not considered conversion.
bool Converted = false;
};
// Set only if CalleeArgInfo is set.
llvm::Optional<PassType> CallPassType;
/// Produce a user-readable information.
markup::Document present() const;
};
inline bool operator==(const HoverInfo::PrintedType &LHS,
const HoverInfo::PrintedType &RHS) {
return std::tie(LHS.Type, LHS.AKA) == std::tie(RHS.Type, RHS.AKA);
}
inline bool operator==(const HoverInfo::PassType &LHS,
const HoverInfo::PassType &RHS) {
return std::tie(LHS.PassBy, LHS.Converted) ==
std::tie(RHS.PassBy, RHS.Converted);
}
// Try to infer structure of a documentation comment (e.g. line breaks).
// FIXME: move to another file so CodeComplete doesn't depend on Hover.
void parseDocumentation(llvm::StringRef Input, markup::Document &Output);
llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const HoverInfo::PrintedType &);
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const HoverInfo::Param &);
inline bool operator==(const HoverInfo::Param &LHS,
const HoverInfo::Param &RHS) {
return std::tie(LHS.Type, LHS.Name, LHS.Default) ==
std::tie(RHS.Type, RHS.Name, RHS.Default);
}
/// Get the hover information when hovering at \p Pos.
llvm::Optional<HoverInfo> getHover(ParsedAST &AST, Position Pos,
format::FormatStyle Style,
const SymbolIndex *Index);
} // namespace clangd
} // namespace clang
#endif
|