17
17
#include " ParsedAST.h"
18
18
#include " Selection.h"
19
19
#include " SourceCode.h"
20
+ #include " SymbolDocumentation.h"
20
21
#include " clang-include-cleaner/Analysis.h"
21
22
#include " clang-include-cleaner/IncludeSpeller.h"
22
23
#include " clang-include-cleaner/Types.h"
40
41
#include " clang/AST/Type.h"
41
42
#include " clang/Basic/CharInfo.h"
42
43
#include " clang/Basic/LLVM.h"
44
+ #include " clang/Basic/LangOptions.h"
43
45
#include " clang/Basic/SourceLocation.h"
44
46
#include " clang/Basic/SourceManager.h"
45
47
#include " clang/Basic/Specifiers.h"
@@ -160,14 +162,14 @@ const char *getMarkdownLanguage(const ASTContext &Ctx) {
160
162
return LangOpts.ObjC ? " objective-c" : " cpp" ;
161
163
}
162
164
163
- HoverInfo::PrintedType printType (QualType QT, ASTContext &ASTCtx,
164
- const PrintingPolicy &PP) {
165
+ SymbolPrintedType printType (QualType QT, ASTContext &ASTCtx,
166
+ const PrintingPolicy &PP) {
165
167
// TypePrinter doesn't resolve decltypes, so resolve them here.
166
168
// FIXME: This doesn't handle composite types that contain a decltype in them.
167
169
// We should rather have a printing policy for that.
168
170
while (!QT.isNull () && QT->isDecltypeType ())
169
171
QT = QT->castAs <DecltypeType>()->getUnderlyingType ();
170
- HoverInfo::PrintedType Result;
172
+ SymbolPrintedType Result;
171
173
llvm::raw_string_ostream OS (Result.Type );
172
174
// Special case: if the outer type is a tag type without qualifiers, then
173
175
// include the tag for extra clarity.
@@ -189,16 +191,16 @@ HoverInfo::PrintedType printType(QualType QT, ASTContext &ASTCtx,
189
191
return Result;
190
192
}
191
193
192
- HoverInfo::PrintedType printType (const TemplateTypeParmDecl *TTP) {
193
- HoverInfo::PrintedType Result;
194
+ SymbolPrintedType printType (const TemplateTypeParmDecl *TTP) {
195
+ SymbolPrintedType Result;
194
196
Result.Type = TTP->wasDeclaredWithTypename () ? " typename" : " class" ;
195
197
if (TTP->isParameterPack ())
196
198
Result.Type += " ..." ;
197
199
return Result;
198
200
}
199
201
200
- HoverInfo::PrintedType printType (const NonTypeTemplateParmDecl *NTTP,
201
- const PrintingPolicy &PP) {
202
+ SymbolPrintedType printType (const NonTypeTemplateParmDecl *NTTP,
203
+ const PrintingPolicy &PP) {
202
204
auto PrintedType = printType (NTTP->getType (), NTTP->getASTContext (), PP);
203
205
if (NTTP->isParameterPack ()) {
204
206
PrintedType.Type += " ..." ;
@@ -208,9 +210,9 @@ HoverInfo::PrintedType printType(const NonTypeTemplateParmDecl *NTTP,
208
210
return PrintedType;
209
211
}
210
212
211
- HoverInfo::PrintedType printType (const TemplateTemplateParmDecl *TTP,
212
- const PrintingPolicy &PP) {
213
- HoverInfo::PrintedType Result;
213
+ SymbolPrintedType printType (const TemplateTemplateParmDecl *TTP,
214
+ const PrintingPolicy &PP) {
215
+ SymbolPrintedType Result;
214
216
llvm::raw_string_ostream OS (Result.Type );
215
217
OS << " template <" ;
216
218
llvm::StringRef Sep = " " ;
@@ -230,14 +232,14 @@ HoverInfo::PrintedType printType(const TemplateTemplateParmDecl *TTP,
230
232
return Result;
231
233
}
232
234
233
- std::vector<HoverInfo::Param >
235
+ std::vector<SymbolParam >
234
236
fetchTemplateParameters (const TemplateParameterList *Params,
235
237
const PrintingPolicy &PP) {
236
238
assert (Params);
237
- std::vector<HoverInfo::Param > TempParameters;
239
+ std::vector<SymbolParam > TempParameters;
238
240
239
241
for (const Decl *Param : *Params) {
240
- HoverInfo::Param P;
242
+ SymbolParam P;
241
243
if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
242
244
P.Type = printType (TTP);
243
245
@@ -351,41 +353,13 @@ void enhanceFromIndex(HoverInfo &Hover, const NamedDecl &ND,
351
353
});
352
354
}
353
355
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
-
382
356
// Populates Type, ReturnType, and Parameters for function-like decls.
383
357
void fillFunctionTypeAndParams (HoverInfo &HI, const Decl *D,
384
358
const FunctionDecl *FD,
385
359
const PrintingPolicy &PP) {
386
360
HI.Parameters .emplace ();
387
361
for (const ParmVarDecl *PVD : FD->parameters ())
388
- HI.Parameters ->emplace_back (toHoverInfoParam (PVD, PP));
362
+ HI.Parameters ->emplace_back (createSymbolParam (PVD, PP));
389
363
390
364
// We don't want any type info, if name already contains it. This is true for
391
365
// constructors/destructors and conversion operators.
@@ -626,6 +600,9 @@ HoverInfo getHoverContents(const NamedDecl *D, const PrintingPolicy &PP,
626
600
HI.Name = printName (Ctx, *D);
627
601
const auto *CommentD = getDeclForComment (D);
628
602
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 ;
629
606
enhanceFromIndex (HI, *CommentD, Index);
630
607
if (HI.Documentation .empty ())
631
608
HI.Documentation = synthesizeDocumentation (D);
@@ -812,7 +789,7 @@ HoverInfo getHoverContents(const DefinedMacro &Macro, const syntax::Token &Tok,
812
789
return HI;
813
790
}
814
791
815
- std::string typeAsDefinition (const HoverInfo::PrintedType &PType) {
792
+ std::string typeAsDefinition (const SymbolPrintedType &PType) {
816
793
std::string Result;
817
794
llvm::raw_string_ostream OS (Result);
818
795
OS << PType.Type ;
@@ -1095,7 +1072,7 @@ void maybeAddCalleeArgInfo(const SelectionTree::Node *N, HoverInfo &HI,
1095
1072
1096
1073
// Extract matching argument from function declaration.
1097
1074
if (const ParmVarDecl *PVD = Parameters[I]) {
1098
- HI.CalleeArgInfo .emplace (toHoverInfoParam (PVD, PP));
1075
+ HI.CalleeArgInfo .emplace (createSymbolParam (PVD, PP));
1099
1076
if (N == &OuterNode)
1100
1077
PassType.PassBy = getPassMode (PVD->getType ());
1101
1078
}
@@ -1455,30 +1432,38 @@ markup::Document HoverInfo::present() const {
1455
1432
1456
1433
// Put a linebreak after header to increase readability.
1457
1434
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
- }
1469
1435
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,
1440
+ ReturnType, Parameters);
1441
+ } else {
1442
+ // Print Types on their own lines to reduce chances of getting line-wrapped
1443
+ // by 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
+ }
1476
1453
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
1462
+ // duplicate the information
1463
+ if (Type && !ReturnType && !Parameters)
1464
+ Output.addParagraph ().appendText (" Type: " ).appendCode (
1465
+ llvm::to_string (*Type));
1466
+ }
1482
1467
1483
1468
if (Value) {
1484
1469
markup::Paragraph &P = Output.addParagraph ();
@@ -1518,9 +1503,6 @@ markup::Document HoverInfo::present() const {
1518
1503
Output.addParagraph ().appendText (OS.str ());
1519
1504
}
1520
1505
1521
- if (!Documentation.empty ())
1522
- parseDocumentation (Documentation, Output);
1523
-
1524
1506
if (!Definition.empty ()) {
1525
1507
Output.addRuler ();
1526
1508
std::string Buffer;
@@ -1646,26 +1628,5 @@ void parseDocumentation(llvm::StringRef Input, markup::Document &Output) {
1646
1628
FlushParagraph ();
1647
1629
}
1648
1630
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
-
1670
1631
} // namespace clangd
1671
1632
} // namespace clang
0 commit comments