1 //===--- CommentBriefParser.cpp - Dumb comment parser ---------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "clang/AST/CommentBriefParser.h"
11 #include "clang/AST/CommentCommandTraits.h"
12 #include "llvm/ADT/StringSwitch.h"
18 inline bool isWhitespace(char C
) {
19 return C
== ' ' || C
== '\n' || C
== '\r' ||
20 C
== '\t' || C
== '\f' || C
== '\v';
23 /// Convert all whitespace into spaces, remove leading and trailing spaces,
24 /// compress multiple spaces into one.
25 void cleanupBrief(std::string
&S
) {
26 bool PrevWasSpace
= true;
27 std::string::iterator O
= S
.begin();
28 for (std::string::iterator I
= S
.begin(), E
= S
.end();
31 if (isWhitespace(C
)) {
42 if (O
!= S
.begin() && *(O
- 1) == ' ')
45 S
.resize(O
- S
.begin());
48 bool isWhitespace(StringRef Text
) {
49 for (StringRef::const_iterator I
= Text
.begin(), E
= Text
.end();
51 if (!isWhitespace(*I
))
56 } // unnamed namespace
58 BriefParser::BriefParser(Lexer
&L
, const CommandTraits
&Traits
) :
59 L(L
), Traits(Traits
) {
60 // Get lookahead token.
64 std::string
BriefParser::Parse() {
65 std::string FirstParagraphOrBrief
;
66 std::string ReturnsParagraph
;
67 bool InFirstParagraph
= true;
69 bool InReturns
= false;
71 while (Tok
.isNot(tok::eof
)) {
72 if (Tok
.is(tok::text
)) {
73 if (InFirstParagraph
|| InBrief
)
74 FirstParagraphOrBrief
+= Tok
.getText();
76 ReturnsParagraph
+= Tok
.getText();
81 if (Tok
.is(tok::backslash_command
) || Tok
.is(tok::at_command
)) {
82 const CommandInfo
*Info
= Traits
.getCommandInfo(Tok
.getCommandID());
83 if (Info
->IsBriefCommand
) {
84 FirstParagraphOrBrief
.clear();
89 if (Info
->IsReturnsCommand
) {
92 InFirstParagraph
= false;
93 ReturnsParagraph
+= "Returns ";
97 // Block commands implicitly start a new paragraph.
98 if (Info
->IsBlockCommand
) {
99 // We found an implicit paragraph end.
100 InFirstParagraph
= false;
106 if (Tok
.is(tok::newline
)) {
107 if (InFirstParagraph
|| InBrief
)
108 FirstParagraphOrBrief
+= ' ';
110 ReturnsParagraph
+= ' ';
113 // If the next token is a whitespace only text, ignore it. Thus we allow
114 // two paragraphs to be separated by line that has only whitespace in it.
116 // We don't need to add a space to the parsed text because we just added
117 // a space for the newline.
118 if (Tok
.is(tok::text
)) {
119 if (isWhitespace(Tok
.getText()))
123 if (Tok
.is(tok::newline
)) {
125 // We found a paragraph end. This ends the brief description if
126 // \\brief command or its equivalent was explicitly used.
127 // Stop scanning text because an explicit \\brief paragraph is the
131 // End first paragraph if we found some non-whitespace text.
132 if (InFirstParagraph
&& !isWhitespace(FirstParagraphOrBrief
))
133 InFirstParagraph
= false;
134 // End the \\returns paragraph because we found the paragraph end.
140 // We didn't handle this token, so just drop it.
144 cleanupBrief(FirstParagraphOrBrief
);
145 if (!FirstParagraphOrBrief
.empty())
146 return FirstParagraphOrBrief
;
148 cleanupBrief(ReturnsParagraph
);
149 return ReturnsParagraph
;
152 } // end namespace comments
153 } // end namespace clang