blob: bc9244a6935ee63897d9386d83b28bc2f3f039e8 [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 Gribenko55e18082012-06-29 18:19:20 +000011#include "llvm/ADT/StringSwitch.h"
Dmitri Gribenko2d44d772012-06-26 20:39:18 +000012
13namespace clang {
14namespace comments {
15
Dmitri Gribenkod558b522012-06-28 01:38:21 +000016namespace {
17/// Convert all whitespace into spaces, remove leading and trailing spaces,
18/// compress multiple spaces into one.
19void cleanupBrief(std::string &S) {
20 bool PrevWasSpace = true;
21 std::string::iterator O = S.begin();
22 for (std::string::iterator I = S.begin(), E = S.end();
23 I != E; ++I) {
24 const char C = *I;
25 if (C == ' ' || C == '\n' || C == '\r' ||
26 C == '\t' || C == '\v' || C == '\f') {
27 if (!PrevWasSpace) {
28 *O++ = ' ';
29 PrevWasSpace = true;
30 }
31 continue;
32 } else {
33 *O++ = C;
34 PrevWasSpace = false;
35 }
36 }
37 if (O != S.begin() && *(O - 1) == ' ')
38 --O;
39
40 S.resize(O - S.begin());
41}
Dmitri Gribenko55e18082012-06-29 18:19:20 +000042
43bool isBlockCommand(StringRef Name) {
44 return llvm::StringSwitch<bool>(Name)
45 .Case("brief", true)
46 .Case("result", true)
47 .Case("return", true)
48 .Case("returns", true)
49 .Case("author", true)
50 .Case("authors", true)
51 .Case("pre", true)
52 .Case("post", true)
53 .Case("param", true)
54 .Case("arg", true)
55 .Default(false);
56}
Dmitri Gribenkod558b522012-06-28 01:38:21 +000057} // unnamed namespace
58
Dmitri Gribenko2d44d772012-06-26 20:39:18 +000059std::string BriefParser::Parse() {
Dmitri Gribenkoc0b83242012-06-27 01:17:34 +000060 std::string Paragraph;
Dmitri Gribenko2d44d772012-06-26 20:39:18 +000061 bool InFirstParagraph = true;
62 bool InBrief = false;
Dmitri Gribenko2d44d772012-06-26 20:39:18 +000063
64 while (Tok.isNot(tok::eof)) {
65 if (Tok.is(tok::text)) {
Dmitri Gribenkoc0b83242012-06-27 01:17:34 +000066 if (InFirstParagraph || InBrief)
67 Paragraph += Tok.getText();
Dmitri Gribenko2d44d772012-06-26 20:39:18 +000068 ConsumeToken();
69 continue;
70 }
71
Dmitri Gribenkof199b9c2012-06-28 00:01:41 +000072 if (Tok.is(tok::command)) {
73 StringRef Name = Tok.getCommandName();
74 if (Name == "brief") {
75 Paragraph.clear();
76 InBrief = true;
77 ConsumeToken();
78 continue;
79 }
Dmitri Gribenko55e18082012-06-29 18:19:20 +000080 // Block commands implicitly start a new paragraph.
81 if (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 Gribenkod558b522012-06-28 01:38:21 +000091 Paragraph += ' ';
Dmitri Gribenko2d44d772012-06-26 20:39:18 +000092 ConsumeToken();
93
94 if (Tok.is(tok::newline)) {
95 ConsumeToken();
96 // We found a paragraph end.
97 InFirstParagraph = false;
Dmitri Gribenko57aceb22012-07-03 18:10:20 +000098 if (InBrief)
Dmitri Gribenkof199b9c2012-06-28 00:01:41 +000099 break;
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000100 }
101 continue;
102 }
103
104 // We didn't handle this token, so just drop it.
105 ConsumeToken();
106 }
107
Dmitri Gribenkod558b522012-06-28 01:38:21 +0000108 cleanupBrief(Paragraph);
Dmitri Gribenkoc0b83242012-06-27 01:17:34 +0000109 return Paragraph;
Dmitri Gribenko2d44d772012-06-26 20:39:18 +0000110}
111
112BriefParser::BriefParser(Lexer &L) : L(L)
113{
114 // Get lookahead token.
115 ConsumeToken();
116}
117
118} // end namespace comments
119} // end namespace clang
120
121