blob: 0aebc1e4e3ddb6a71606f4c39b7048645e1edfcb [file] [log] [blame]
Dmitri Gribenko2d44d772012-06-26 20:39:18 +00001//===--- CommentBriefParser.cpp - Dumb comment parser ---------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "clang/AST/CommentBriefParser.h"
Dmitri Gribenkoaa580812012-08-09 00:03:17 +000011#include "clang/AST/CommentCommandTraits.h"
Dmitri Gribenko55e18082012-06-29 18:19:20 +000012#include "llvm/ADT/StringSwitch.h"
Dmitri Gribenko2d44d772012-06-26 20:39:18 +000013
14namespace clang {
15namespace comments {
16
Dmitri Gribenkod558b522012-06-28 01:38:21 +000017namespace {
18/// Convert all whitespace into spaces, remove leading and trailing spaces,
19/// compress multiple spaces into one.
20void 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 (C == ' ' || C == '\n' || C == '\r' ||
27 C == '\t' || C == '\v' || C == '\f') {
28 if (!PrevWasSpace) {
29 *O++ = ' ';
30 PrevWasSpace = true;
31 }
32 continue;
33 } else {
34 *O++ = C;
35 PrevWasSpace = false;
36 }
37 }
38 if (O != S.begin() && *(O - 1) == ' ')
39 --O;
40
41 S.resize(O - S.begin());
42}
43} // unnamed namespace
44
Dmitri Gribenkoaa580812012-08-09 00:03:17 +000045BriefParser::BriefParser(Lexer &L, const CommandTraits &Traits) :
46 L(L), Traits(Traits) {
47 // Get lookahead token.
48 ConsumeToken();
49}
50
Dmitri Gribenko2d44d772012-06-26 20:39:18 +000051std::string BriefParser::Parse() {
Dmitri Gribenko72021ff2012-07-20 17:01:34 +000052 std::string FirstParagraphOrBrief;
53 std::string ReturnsParagraph;
Dmitri Gribenko2d44d772012-06-26 20:39:18 +000054 bool InFirstParagraph = true;
55 bool InBrief = false;
Dmitri Gribenko72021ff2012-07-20 17:01:34 +000056 bool InReturns = false;
Dmitri Gribenko2d44d772012-06-26 20:39:18 +000057
58 while (Tok.isNot(tok::eof)) {
59 if (Tok.is(tok::text)) {
Dmitri Gribenkoc0b83242012-06-27 01:17:34 +000060 if (InFirstParagraph || InBrief)
Dmitri Gribenko72021ff2012-07-20 17:01:34 +000061 FirstParagraphOrBrief += Tok.getText();
62 else if (InReturns)
63 ReturnsParagraph += Tok.getText();
Dmitri Gribenko2d44d772012-06-26 20:39:18 +000064 ConsumeToken();
65 continue;
66 }
67
Dmitri Gribenkof199b9c2012-06-28 00:01:41 +000068 if (Tok.is(tok::command)) {
69 StringRef Name = Tok.getCommandName();
Dmitri Gribenkoaa580812012-08-09 00:03:17 +000070 if (Traits.isBriefCommand(Name)) {
Dmitri Gribenko72021ff2012-07-20 17:01:34 +000071 FirstParagraphOrBrief.clear();
Dmitri Gribenkof199b9c2012-06-28 00:01:41 +000072 InBrief = true;
73 ConsumeToken();
74 continue;
75 }
Dmitri Gribenkoaa580812012-08-09 00:03:17 +000076 if (Traits.isReturnsCommand(Name)) {
Dmitri Gribenko72021ff2012-07-20 17:01:34 +000077 InReturns = true;
78 ReturnsParagraph += "Returns ";
79 }
Dmitri Gribenko55e18082012-06-29 18:19:20 +000080 // Block commands implicitly start a new paragraph.
Dmitri Gribenkoaa580812012-08-09 00:03:17 +000081 if (Traits.isBlockCommand(Name)) {
Dmitri Gribenkof199b9c2012-06-28 00:01:41 +000082 // We found an implicit paragraph end.
83 InFirstParagraph = false;
Dmitri Gribenko57aceb22012-07-03 18:10:20 +000084 if (InBrief)
Dmitri Gribenkof199b9c2012-06-28 00:01:41 +000085 break;
Dmitri Gribenkof199b9c2012-06-28 00:01:41 +000086 }
Dmitri Gribenko2d44d772012-06-26 20:39:18 +000087 }
88
89 if (Tok.is(tok::newline)) {
Dmitri Gribenkoc0b83242012-06-27 01:17:34 +000090 if (InFirstParagraph || InBrief)
Dmitri Gribenko72021ff2012-07-20 17:01:34 +000091 FirstParagraphOrBrief += ' ';
92 else if (InReturns)
93 ReturnsParagraph += ' ';
Dmitri Gribenko2d44d772012-06-26 20:39:18 +000094 ConsumeToken();
95
96 if (Tok.is(tok::newline)) {
97 ConsumeToken();
98 // We found a paragraph end.
99 InFirstParagraph = false;
Dmitri Gribenko72021ff2012-07-20 17:01:34 +0000100 InReturns = false;
Dmitri Gribenko57aceb22012-07-03 18:10:20 +0000101 if (InBrief)
Dmitri Gribenkof199b9c2012-06-28 00:01:41 +0000102 break;
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000103 }
104 continue;
105 }
106
107 // We didn't handle this token, so just drop it.
108 ConsumeToken();
109 }
110
Dmitri Gribenko72021ff2012-07-20 17:01:34 +0000111 cleanupBrief(FirstParagraphOrBrief);
112 if (!FirstParagraphOrBrief.empty())
113 return FirstParagraphOrBrief;
114
115 cleanupBrief(ReturnsParagraph);
116 return ReturnsParagraph;
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000117}
118
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000119} // end namespace comments
120} // end namespace clang
121
122