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