1717#include " ParsedAST.h"
1818#include " Selection.h"
1919#include " SourceCode.h"
20+ #include " SymbolDocumentation.h"
2021#include " clang-include-cleaner/Analysis.h"
2122#include " clang-include-cleaner/IncludeSpeller.h"
2223#include " clang-include-cleaner/Types.h"
4041#include " clang/AST/Type.h"
4142#include " clang/Basic/CharInfo.h"
4243#include " clang/Basic/LLVM.h"
44+ #include " clang/Basic/LangOptions.h"
4345#include " clang/Basic/SourceLocation.h"
4446#include " clang/Basic/SourceManager.h"
4547#include " clang/Basic/Specifiers.h"
@@ -160,14 +162,14 @@ const char *getMarkdownLanguage(const ASTContext &Ctx) {
160162 return LangOpts.ObjC ? " objective-c" : " cpp" ;
161163}
162164
163- HoverInfo::PrintedType printType (QualType QT, ASTContext &ASTCtx,
165+ SymbolPrintedType printType (QualType QT, ASTContext &ASTCtx,
164166 const PrintingPolicy &PP) {
165167 // TypePrinter doesn't resolve decltypes, so resolve them here.
166168 // FIXME: This doesn't handle composite types that contain a decltype in them.
167169 // We should rather have a printing policy for that.
168170 while (!QT.isNull () && QT->isDecltypeType ())
169171 QT = QT->castAs <DecltypeType>()->getUnderlyingType ();
170- HoverInfo::PrintedType Result;
172+ SymbolPrintedType Result;
171173 llvm::raw_string_ostream OS (Result.Type );
172174 // Special case: if the outer type is a tag type without qualifiers, then
173175 // include the tag for extra clarity.
@@ -189,15 +191,15 @@ HoverInfo::PrintedType printType(QualType QT, ASTContext &ASTCtx,
189191 return Result;
190192}
191193
192- HoverInfo::PrintedType printType (const TemplateTypeParmDecl *TTP) {
193- HoverInfo::PrintedType Result;
194+ SymbolPrintedType printType (const TemplateTypeParmDecl *TTP) {
195+ SymbolPrintedType Result;
194196 Result.Type = TTP->wasDeclaredWithTypename () ? " typename" : " class" ;
195197 if (TTP->isParameterPack ())
196198 Result.Type += " ..." ;
197199 return Result;
198200}
199201
200- HoverInfo::PrintedType printType (const NonTypeTemplateParmDecl *NTTP,
202+ SymbolPrintedType printType (const NonTypeTemplateParmDecl *NTTP,
201203 const PrintingPolicy &PP) {
202204 auto PrintedType = printType (NTTP->getType (), NTTP->getASTContext (), PP);
203205 if (NTTP->isParameterPack ()) {
@@ -208,9 +210,9 @@ HoverInfo::PrintedType printType(const NonTypeTemplateParmDecl *NTTP,
208210 return PrintedType;
209211}
210212
211- HoverInfo::PrintedType printType (const TemplateTemplateParmDecl *TTP,
213+ SymbolPrintedType printType (const TemplateTemplateParmDecl *TTP,
212214 const PrintingPolicy &PP) {
213- HoverInfo::PrintedType Result;
215+ SymbolPrintedType Result;
214216 llvm::raw_string_ostream OS (Result.Type );
215217 OS << " template <" ;
216218 llvm::StringRef Sep = " " ;
@@ -230,14 +232,14 @@ HoverInfo::PrintedType printType(const TemplateTemplateParmDecl *TTP,
230232 return Result;
231233}
232234
233- std::vector<HoverInfo::Param >
235+ std::vector<SymbolParam >
234236fetchTemplateParameters (const TemplateParameterList *Params,
235237 const PrintingPolicy &PP) {
236238 assert (Params);
237- std::vector<HoverInfo::Param > TempParameters;
239+ std::vector<SymbolParam > TempParameters;
238240
239241 for (const Decl *Param : *Params) {
240- HoverInfo::Param P;
242+ SymbolParam P;
241243 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
242244 P.Type = printType (TTP);
243245
@@ -351,41 +353,13 @@ void enhanceFromIndex(HoverInfo &Hover, const NamedDecl &ND,
351353 });
352354}
353355
354- // Default argument might exist but be unavailable, in the case of unparsed
355- // arguments for example. This function returns the default argument if it is
356- // available.
357- const Expr *getDefaultArg (const ParmVarDecl *PVD) {
358- // Default argument can be unparsed or uninstantiated. For the former we
359- // can't do much, as token information is only stored in Sema and not
360- // attached to the AST node. For the latter though, it is safe to proceed as
361- // the expression is still valid.
362- if (!PVD->hasDefaultArg () || PVD->hasUnparsedDefaultArg ())
363- return nullptr ;
364- return PVD->hasUninstantiatedDefaultArg () ? PVD->getUninstantiatedDefaultArg ()
365- : PVD->getDefaultArg ();
366- }
367-
368- HoverInfo::Param toHoverInfoParam (const ParmVarDecl *PVD,
369- const PrintingPolicy &PP) {
370- HoverInfo::Param Out;
371- Out.Type = printType (PVD->getType (), PVD->getASTContext (), PP);
372- if (!PVD->getName ().empty ())
373- Out.Name = PVD->getNameAsString ();
374- if (const Expr *DefArg = getDefaultArg (PVD)) {
375- Out.Default .emplace ();
376- llvm::raw_string_ostream OS (*Out.Default );
377- DefArg->printPretty (OS, nullptr , PP);
378- }
379- return Out;
380- }
381-
382356// Populates Type, ReturnType, and Parameters for function-like decls.
383357void fillFunctionTypeAndParams (HoverInfo &HI, const Decl *D,
384358 const FunctionDecl *FD,
385359 const PrintingPolicy &PP) {
386360 HI.Parameters .emplace ();
387361 for (const ParmVarDecl *PVD : FD->parameters ())
388- HI.Parameters ->emplace_back (toHoverInfoParam (PVD, PP));
362+ HI.Parameters ->emplace_back (createSymbolParam (PVD, PP));
389363
390364 // We don't want any type info, if name already contains it. This is true for
391365 // constructors/destructors and conversion operators.
@@ -626,6 +600,9 @@ HoverInfo getHoverContents(const NamedDecl *D, const PrintingPolicy &PP,
626600 HI.Name = printName (Ctx, *D);
627601 const auto *CommentD = getDeclForComment (D);
628602 HI.Documentation = getDeclComment (Ctx, *CommentD);
603+ // safe the language options to be able to create the comment::CommandTraits
604+ // to parse the documentation
605+ HI.CommentOpts = D->getASTContext ().getLangOpts ().CommentOpts ;
629606 enhanceFromIndex (HI, *CommentD, Index);
630607 if (HI.Documentation .empty ())
631608 HI.Documentation = synthesizeDocumentation (D);
@@ -812,7 +789,7 @@ HoverInfo getHoverContents(const DefinedMacro &Macro, const syntax::Token &Tok,
812789 return HI;
813790}
814791
815- std::string typeAsDefinition (const HoverInfo::PrintedType &PType) {
792+ std::string typeAsDefinition (const SymbolPrintedType &PType) {
816793 std::string Result;
817794 llvm::raw_string_ostream OS (Result);
818795 OS << PType.Type ;
@@ -1095,7 +1072,7 @@ void maybeAddCalleeArgInfo(const SelectionTree::Node *N, HoverInfo &HI,
10951072
10961073 // Extract matching argument from function declaration.
10971074 if (const ParmVarDecl *PVD = Parameters[I]) {
1098- HI.CalleeArgInfo .emplace (toHoverInfoParam (PVD, PP));
1075+ HI.CalleeArgInfo .emplace (createSymbolParam (PVD, PP));
10991076 if (N == &OuterNode)
11001077 PassType.PassBy = getPassMode (PVD->getType ());
11011078 }
@@ -1455,30 +1432,38 @@ markup::Document HoverInfo::present() const {
14551432
14561433 // Put a linebreak after header to increase readability.
14571434 Output.addRuler ();
1458- // Print Types on their own lines to reduce chances of getting line-wrapped by
1459- // editor, as they might be long.
1460- if (ReturnType) {
1461- // For functions we display signature in a list form, e.g.:
1462- // → `x`
1463- // Parameters:
1464- // - `bool param1`
1465- // - `int param2 = 5`
1466- Output.addParagraph ().appendText (" → " ).appendCode (
1467- llvm::to_string (*ReturnType));
1468- }
14691435
1470- if (Parameters && !Parameters->empty ()) {
1471- Output.addParagraph ().appendText (" Parameters: " );
1472- markup::BulletList &L = Output.addBulletList ();
1473- for (const auto &Param : *Parameters)
1474- L.addItem ().addParagraph ().appendCode (llvm::to_string (Param));
1475- }
1436+ if (!Documentation.empty ()) {
1437+ llvm::BumpPtrAllocator Allocator;
1438+ comments::CommandTraits Traits (Allocator, CommentOpts);
1439+ docCommentToMarkup (Output, Documentation, Allocator, Traits, Type, ReturnType,
1440+ Parameters);
1441+ } else {
1442+ // Print Types on their own lines to reduce chances of getting line-wrapped by
1443+ // editor, as they might be long.
1444+ if (ReturnType) {
1445+ // For functions we display signature in a list form, e.g.:
1446+ // → `x`
1447+ // Parameters:
1448+ // - `bool param1`
1449+ // - `int param2 = 5`
1450+ Output.addParagraph ().appendText (" → " ).appendCode (
1451+ llvm::to_string (*ReturnType));
1452+ }
14761453
1477- // Don't print Type after Parameters or ReturnType as this will just duplicate
1478- // the information
1479- if (Type && !ReturnType && !Parameters)
1480- Output.addParagraph ().appendText (" Type: " ).appendCode (
1481- llvm::to_string (*Type));
1454+ if (Parameters && !Parameters->empty ()) {
1455+ Output.addParagraph ().appendText (" Parameters: " );
1456+ markup::BulletList &L = Output.addBulletList ();
1457+ for (const auto &Param : *Parameters)
1458+ L.addItem ().addParagraph ().appendCode (llvm::to_string (Param));
1459+ }
1460+
1461+ // Don't print Type after Parameters or ReturnType as this will just duplicate
1462+ // the information
1463+ if (Type && !ReturnType && !Parameters)
1464+ Output.addParagraph ().appendText (" Type: " ).appendCode (
1465+ llvm::to_string (*Type));
1466+ }
14821467
14831468 if (Value) {
14841469 markup::Paragraph &P = Output.addParagraph ();
@@ -1518,9 +1503,6 @@ markup::Document HoverInfo::present() const {
15181503 Output.addParagraph ().appendText (OS.str ());
15191504 }
15201505
1521- if (!Documentation.empty ())
1522- parseDocumentation (Documentation, Output);
1523-
15241506 if (!Definition.empty ()) {
15251507 Output.addRuler ();
15261508 std::string Buffer;
@@ -1646,26 +1628,5 @@ void parseDocumentation(llvm::StringRef Input, markup::Document &Output) {
16461628 FlushParagraph ();
16471629}
16481630
1649- llvm::raw_ostream &operator <<(llvm::raw_ostream &OS,
1650- const HoverInfo::PrintedType &T) {
1651- OS << T.Type ;
1652- if (T.AKA )
1653- OS << " (aka " << *T.AKA << " )" ;
1654- return OS;
1655- }
1656-
1657- llvm::raw_ostream &operator <<(llvm::raw_ostream &OS,
1658- const HoverInfo::Param &P) {
1659- if (P.Type )
1660- OS << P.Type ->Type ;
1661- if (P.Name )
1662- OS << " " << *P.Name ;
1663- if (P.Default )
1664- OS << " = " << *P.Default ;
1665- if (P.Type && P.Type ->AKA )
1666- OS << " (aka " << *P.Type ->AKA << " )" ;
1667- return OS;
1668- }
1669-
16701631} // namespace clangd
16711632} // namespace clang
0 commit comments