clang  20.0.0git
CommentBriefParser.cpp
Go to the documentation of this file.
1 //===--- CommentBriefParser.cpp - Dumb comment parser ---------------------===//
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 
11 #include "clang/Basic/CharInfo.h"
12 
13 namespace clang {
14 namespace comments {
15 
16 namespace {
17 
18 /// Convert all whitespace into spaces, remove leading and trailing spaces,
19 /// compress multiple spaces into one.
20 void cleanupBrief(std::string &S) {
21  bool PrevWasSpace = true;
22  std::string::iterator O = S.begin();
23  for (std::string::iterator I = S.begin(), E = S.end();
24  I != E; ++I) {
25  const char C = *I;
26  if (clang::isWhitespace(C)) {
27  if (!PrevWasSpace) {
28  *O++ = ' ';
29  PrevWasSpace = true;
30  }
31  } else {
32  *O++ = C;
33  PrevWasSpace = false;
34  }
35  }
36  if (O != S.begin() && *(O - 1) == ' ')
37  --O;
38 
39  S.resize(O - S.begin());
40 }
41 
42 bool isWhitespace(StringRef Text) {
43  return llvm::all_of(Text, clang::isWhitespace);
44 }
45 } // unnamed namespace
46 
48  L(L), Traits(Traits) {
49  // Get lookahead token.
50  ConsumeToken();
51 }
52 
53 std::string BriefParser::Parse() {
54  std::string FirstParagraphOrBrief;
55  std::string ReturnsParagraph;
56  bool InFirstParagraph = true;
57  bool InBrief = false;
58  bool InReturns = false;
59 
60  while (Tok.isNot(tok::eof)) {
61  if (Tok.is(tok::text)) {
62  if (InFirstParagraph || InBrief)
63  FirstParagraphOrBrief += Tok.getText();
64  else if (InReturns)
65  ReturnsParagraph += Tok.getText();
66  ConsumeToken();
67  continue;
68  }
69 
70  if (Tok.is(tok::backslash_command) || Tok.is(tok::at_command)) {
71  const CommandInfo *Info = Traits.getCommandInfo(Tok.getCommandID());
72  if (Info->IsBriefCommand) {
73  FirstParagraphOrBrief.clear();
74  InBrief = true;
75  ConsumeToken();
76  continue;
77  }
78  if (Info->IsReturnsCommand) {
79  InReturns = true;
80  InBrief = false;
81  InFirstParagraph = false;
82  ReturnsParagraph += "Returns ";
83  ConsumeToken();
84  continue;
85  }
86  // Block commands implicitly start a new paragraph.
87  if (Info->IsBlockCommand) {
88  // We found an implicit paragraph end.
89  InFirstParagraph = false;
90  if (InBrief)
91  break;
92  }
93  }
94 
95  if (Tok.is(tok::newline)) {
96  if (InFirstParagraph || InBrief)
97  FirstParagraphOrBrief += ' ';
98  else if (InReturns)
99  ReturnsParagraph += ' ';
100  ConsumeToken();
101 
102  // If the next token is a whitespace only text, ignore it. Thus we allow
103  // two paragraphs to be separated by line that has only whitespace in it.
104  //
105  // We don't need to add a space to the parsed text because we just added
106  // a space for the newline.
107  if (Tok.is(tok::text)) {
108  if (isWhitespace(Tok.getText()))
109  ConsumeToken();
110  }
111 
112  if (Tok.is(tok::newline)) {
113  ConsumeToken();
114  // We found a paragraph end. This ends the brief description if
115  // \command or its equivalent was explicitly used.
116  // Stop scanning text because an explicit \paragraph is the
117  // preferred one.
118  if (InBrief)
119  break;
120  // End first paragraph if we found some non-whitespace text.
121  if (InFirstParagraph && !isWhitespace(FirstParagraphOrBrief))
122  InFirstParagraph = false;
123  // End the \\returns paragraph because we found the paragraph end.
124  InReturns = false;
125  }
126  continue;
127  }
128 
129  // We didn't handle this token, so just drop it.
130  ConsumeToken();
131  }
132 
133  cleanupBrief(FirstParagraphOrBrief);
134  if (!FirstParagraphOrBrief.empty())
135  return FirstParagraphOrBrief;
136 
137  cleanupBrief(ReturnsParagraph);
138  return ReturnsParagraph;
139 }
140 
141 } // end namespace comments
142 } // end namespace clang
143 
144 
Expr * E
StringRef Text
Definition: Format.cpp:3002
std::string Parse()
Return the best "brief description" we can find.
BriefParser(Lexer &L, const CommandTraits &Traits)
This class provides information about commands that can be used in comments.
const CommandInfo * getCommandInfo(StringRef Name) const
bool isNot(tok::TokenKind K) const LLVM_READONLY
Definition: CommentLexer.h:93
unsigned getCommandID() const LLVM_READONLY
Definition: CommentLexer.h:120
StringRef getText() const LLVM_READONLY
Definition: CommentLexer.h:98
bool is(tok::TokenKind K) const LLVM_READONLY
Definition: CommentLexer.h:92
The JSON file list parser is used to communicate input to InstallAPI.
LLVM_READONLY bool isWhitespace(unsigned char c)
Return true if this character is horizontal or vertical ASCII whitespace: ' ', '\t',...
Definition: CharInfo.h:108
Information about a single command.
unsigned IsBlockCommand
True if this command is a block command (of any kind).
unsigned IsReturnsCommand
True if this command is \returns or an alias.
unsigned IsBriefCommand
True if this command is introducing a brief documentation paragraph (\or an alias).