CommentParser.cpp 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445
  1. //===- unittests/AST/CommentParser.cpp ------ Comment parser tests --------===//
  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. #include "clang/AST/CommentParser.h"
  9. #include "clang/AST/Comment.h"
  10. #include "clang/AST/CommentCommandTraits.h"
  11. #include "clang/AST/CommentLexer.h"
  12. #include "clang/AST/CommentSema.h"
  13. #include "clang/Basic/CommentOptions.h"
  14. #include "clang/Basic/Diagnostic.h"
  15. #include "clang/Basic/DiagnosticOptions.h"
  16. #include "clang/Basic/FileManager.h"
  17. #include "clang/Basic/SourceManager.h"
  18. #include "llvm/ADT/STLExtras.h"
  19. #include "llvm/Support/Allocator.h"
  20. #include "gtest/gtest.h"
  21. using namespace llvm;
  22. using namespace clang;
  23. namespace clang {
  24. namespace comments {
  25. namespace {
  26. const bool MY_DEBUG = true;
  27. class CommentParserTest : public ::testing::Test {
  28. protected:
  29. CommentParserTest()
  30. : FileMgr(FileMgrOpts),
  31. DiagID(new DiagnosticIDs()),
  32. Diags(DiagID, new DiagnosticOptions, new IgnoringDiagConsumer()),
  33. SourceMgr(Diags, FileMgr),
  34. Traits(Allocator, CommentOptions()) {
  35. }
  36. FileSystemOptions FileMgrOpts;
  37. FileManager FileMgr;
  38. IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
  39. DiagnosticsEngine Diags;
  40. SourceManager SourceMgr;
  41. llvm::BumpPtrAllocator Allocator;
  42. CommandTraits Traits;
  43. FullComment *parseString(const char *Source);
  44. };
  45. FullComment *CommentParserTest::parseString(const char *Source) {
  46. std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Source);
  47. FileID File = SourceMgr.createFileID(std::move(Buf));
  48. SourceLocation Begin = SourceMgr.getLocForStartOfFile(File);
  49. Lexer L(Allocator, Diags, Traits, Begin, Source, Source + strlen(Source));
  50. Sema S(Allocator, SourceMgr, Diags, Traits, /*PP=*/ nullptr);
  51. Parser P(L, S, Allocator, SourceMgr, Diags, Traits);
  52. FullComment *FC = P.parseFullComment();
  53. if (MY_DEBUG) {
  54. llvm::errs() << "=== Source:\n" << Source << "\n=== AST:\n";
  55. FC->dump(llvm::errs(), &Traits, &SourceMgr);
  56. }
  57. Token Tok;
  58. L.lex(Tok);
  59. if (Tok.is(tok::eof))
  60. return FC;
  61. else
  62. return nullptr;
  63. }
  64. ::testing::AssertionResult HasChildCount(const Comment *C, size_t Count) {
  65. if (!C)
  66. return ::testing::AssertionFailure() << "Comment is NULL";
  67. if (Count != C->child_count())
  68. return ::testing::AssertionFailure()
  69. << "Count = " << Count
  70. << ", child_count = " << C->child_count();
  71. return ::testing::AssertionSuccess();
  72. }
  73. template <typename T>
  74. ::testing::AssertionResult GetChildAt(const Comment *C,
  75. size_t Idx,
  76. T *&Child) {
  77. if (!C)
  78. return ::testing::AssertionFailure() << "Comment is NULL";
  79. if (Idx >= C->child_count())
  80. return ::testing::AssertionFailure()
  81. << "Idx out of range. Idx = " << Idx
  82. << ", child_count = " << C->child_count();
  83. Comment::child_iterator I = C->child_begin() + Idx;
  84. Comment *CommentChild = *I;
  85. if (!CommentChild)
  86. return ::testing::AssertionFailure() << "Child is NULL";
  87. Child = dyn_cast<T>(CommentChild);
  88. if (!Child)
  89. return ::testing::AssertionFailure()
  90. << "Child is not of requested type, but a "
  91. << CommentChild->getCommentKindName();
  92. return ::testing::AssertionSuccess();
  93. }
  94. ::testing::AssertionResult HasTextAt(const Comment *C,
  95. size_t Idx,
  96. StringRef Text) {
  97. TextComment *TC;
  98. ::testing::AssertionResult AR = GetChildAt(C, Idx, TC);
  99. if (!AR)
  100. return AR;
  101. StringRef ActualText = TC->getText();
  102. if (ActualText != Text)
  103. return ::testing::AssertionFailure()
  104. << "TextComment has text \"" << ActualText.str() << "\", "
  105. "expected \"" << Text.str() << "\"";
  106. if (TC->hasTrailingNewline())
  107. return ::testing::AssertionFailure()
  108. << "TextComment has a trailing newline";
  109. return ::testing::AssertionSuccess();
  110. }
  111. ::testing::AssertionResult HasTextWithNewlineAt(const Comment *C,
  112. size_t Idx,
  113. StringRef Text) {
  114. TextComment *TC;
  115. ::testing::AssertionResult AR = GetChildAt(C, Idx, TC);
  116. if (!AR)
  117. return AR;
  118. StringRef ActualText = TC->getText();
  119. if (ActualText != Text)
  120. return ::testing::AssertionFailure()
  121. << "TextComment has text \"" << ActualText.str() << "\", "
  122. "expected \"" << Text.str() << "\"";
  123. if (!TC->hasTrailingNewline())
  124. return ::testing::AssertionFailure()
  125. << "TextComment has no trailing newline";
  126. return ::testing::AssertionSuccess();
  127. }
  128. ::testing::AssertionResult HasBlockCommandAt(const Comment *C,
  129. const CommandTraits &Traits,
  130. size_t Idx,
  131. BlockCommandComment *&BCC,
  132. StringRef Name,
  133. ParagraphComment *&Paragraph) {
  134. ::testing::AssertionResult AR = GetChildAt(C, Idx, BCC);
  135. if (!AR)
  136. return AR;
  137. StringRef ActualName = BCC->getCommandName(Traits);
  138. if (ActualName != Name)
  139. return ::testing::AssertionFailure()
  140. << "BlockCommandComment has name \"" << ActualName.str() << "\", "
  141. "expected \"" << Name.str() << "\"";
  142. Paragraph = BCC->getParagraph();
  143. return ::testing::AssertionSuccess();
  144. }
  145. ::testing::AssertionResult HasParamCommandAt(
  146. const Comment *C,
  147. const CommandTraits &Traits,
  148. size_t Idx,
  149. ParamCommandComment *&PCC,
  150. StringRef CommandName,
  151. ParamCommandComment::PassDirection Direction,
  152. bool IsDirectionExplicit,
  153. StringRef ParamName,
  154. ParagraphComment *&Paragraph) {
  155. ::testing::AssertionResult AR = GetChildAt(C, Idx, PCC);
  156. if (!AR)
  157. return AR;
  158. StringRef ActualCommandName = PCC->getCommandName(Traits);
  159. if (ActualCommandName != CommandName)
  160. return ::testing::AssertionFailure()
  161. << "ParamCommandComment has name \"" << ActualCommandName.str() << "\", "
  162. "expected \"" << CommandName.str() << "\"";
  163. if (PCC->getDirection() != Direction)
  164. return ::testing::AssertionFailure()
  165. << "ParamCommandComment has direction " << PCC->getDirection() << ", "
  166. "expected " << Direction;
  167. if (PCC->isDirectionExplicit() != IsDirectionExplicit)
  168. return ::testing::AssertionFailure()
  169. << "ParamCommandComment has "
  170. << (PCC->isDirectionExplicit() ? "explicit" : "implicit")
  171. << " direction, "
  172. "expected " << (IsDirectionExplicit ? "explicit" : "implicit");
  173. if (!ParamName.empty() && !PCC->hasParamName())
  174. return ::testing::AssertionFailure()
  175. << "ParamCommandComment has no parameter name";
  176. StringRef ActualParamName = PCC->hasParamName() ? PCC->getParamNameAsWritten() : "";
  177. if (ActualParamName != ParamName)
  178. return ::testing::AssertionFailure()
  179. << "ParamCommandComment has parameter name \"" << ActualParamName.str()
  180. << "\", "
  181. "expected \"" << ParamName.str() << "\"";
  182. Paragraph = PCC->getParagraph();
  183. return ::testing::AssertionSuccess();
  184. }
  185. ::testing::AssertionResult HasTParamCommandAt(
  186. const Comment *C,
  187. const CommandTraits &Traits,
  188. size_t Idx,
  189. TParamCommandComment *&TPCC,
  190. StringRef CommandName,
  191. StringRef ParamName,
  192. ParagraphComment *&Paragraph) {
  193. ::testing::AssertionResult AR = GetChildAt(C, Idx, TPCC);
  194. if (!AR)
  195. return AR;
  196. StringRef ActualCommandName = TPCC->getCommandName(Traits);
  197. if (ActualCommandName != CommandName)
  198. return ::testing::AssertionFailure()
  199. << "TParamCommandComment has name \"" << ActualCommandName.str() << "\", "
  200. "expected \"" << CommandName.str() << "\"";
  201. if (!ParamName.empty() && !TPCC->hasParamName())
  202. return ::testing::AssertionFailure()
  203. << "TParamCommandComment has no parameter name";
  204. StringRef ActualParamName = TPCC->hasParamName() ? TPCC->getParamNameAsWritten() : "";
  205. if (ActualParamName != ParamName)
  206. return ::testing::AssertionFailure()
  207. << "TParamCommandComment has parameter name \"" << ActualParamName.str()
  208. << "\", "
  209. "expected \"" << ParamName.str() << "\"";
  210. Paragraph = TPCC->getParagraph();
  211. return ::testing::AssertionSuccess();
  212. }
  213. ::testing::AssertionResult HasInlineCommandAt(const Comment *C,
  214. const CommandTraits &Traits,
  215. size_t Idx,
  216. InlineCommandComment *&ICC,
  217. StringRef Name) {
  218. ::testing::AssertionResult AR = GetChildAt(C, Idx, ICC);
  219. if (!AR)
  220. return AR;
  221. StringRef ActualName = ICC->getCommandName(Traits);
  222. if (ActualName != Name)
  223. return ::testing::AssertionFailure()
  224. << "InlineCommandComment has name \"" << ActualName.str() << "\", "
  225. "expected \"" << Name.str() << "\"";
  226. return ::testing::AssertionSuccess();
  227. }
  228. struct NoArgs {};
  229. ::testing::AssertionResult HasInlineCommandAt(const Comment *C,
  230. const CommandTraits &Traits,
  231. size_t Idx,
  232. InlineCommandComment *&ICC,
  233. StringRef Name,
  234. NoArgs) {
  235. ::testing::AssertionResult AR = HasInlineCommandAt(C, Traits, Idx, ICC, Name);
  236. if (!AR)
  237. return AR;
  238. if (ICC->getNumArgs() != 0)
  239. return ::testing::AssertionFailure()
  240. << "InlineCommandComment has " << ICC->getNumArgs() << " arg(s), "
  241. "expected 0";
  242. return ::testing::AssertionSuccess();
  243. }
  244. ::testing::AssertionResult HasInlineCommandAt(const Comment *C,
  245. const CommandTraits &Traits,
  246. size_t Idx,
  247. InlineCommandComment *&ICC,
  248. StringRef Name,
  249. StringRef Arg) {
  250. ::testing::AssertionResult AR = HasInlineCommandAt(C, Traits, Idx, ICC, Name);
  251. if (!AR)
  252. return AR;
  253. if (ICC->getNumArgs() != 1)
  254. return ::testing::AssertionFailure()
  255. << "InlineCommandComment has " << ICC->getNumArgs() << " arg(s), "
  256. "expected 1";
  257. StringRef ActualArg = ICC->getArgText(0);
  258. if (ActualArg != Arg)
  259. return ::testing::AssertionFailure()
  260. << "InlineCommandComment has argument \"" << ActualArg.str() << "\", "
  261. "expected \"" << Arg.str() << "\"";
  262. return ::testing::AssertionSuccess();
  263. }
  264. ::testing::AssertionResult HasHTMLStartTagAt(const Comment *C,
  265. size_t Idx,
  266. HTMLStartTagComment *&HST,
  267. StringRef TagName) {
  268. ::testing::AssertionResult AR = GetChildAt(C, Idx, HST);
  269. if (!AR)
  270. return AR;
  271. StringRef ActualTagName = HST->getTagName();
  272. if (ActualTagName != TagName)
  273. return ::testing::AssertionFailure()
  274. << "HTMLStartTagComment has name \"" << ActualTagName.str() << "\", "
  275. "expected \"" << TagName.str() << "\"";
  276. return ::testing::AssertionSuccess();
  277. }
  278. struct SelfClosing {};
  279. ::testing::AssertionResult HasHTMLStartTagAt(const Comment *C,
  280. size_t Idx,
  281. HTMLStartTagComment *&HST,
  282. StringRef TagName,
  283. SelfClosing) {
  284. ::testing::AssertionResult AR = HasHTMLStartTagAt(C, Idx, HST, TagName);
  285. if (!AR)
  286. return AR;
  287. if (!HST->isSelfClosing())
  288. return ::testing::AssertionFailure()
  289. << "HTMLStartTagComment is not self-closing";
  290. return ::testing::AssertionSuccess();
  291. }
  292. struct NoAttrs {};
  293. ::testing::AssertionResult HasHTMLStartTagAt(const Comment *C,
  294. size_t Idx,
  295. HTMLStartTagComment *&HST,
  296. StringRef TagName,
  297. NoAttrs) {
  298. ::testing::AssertionResult AR = HasHTMLStartTagAt(C, Idx, HST, TagName);
  299. if (!AR)
  300. return AR;
  301. if (HST->isSelfClosing())
  302. return ::testing::AssertionFailure()
  303. << "HTMLStartTagComment is self-closing";
  304. if (HST->getNumAttrs() != 0)
  305. return ::testing::AssertionFailure()
  306. << "HTMLStartTagComment has " << HST->getNumAttrs() << " attr(s), "
  307. "expected 0";
  308. return ::testing::AssertionSuccess();
  309. }
  310. ::testing::AssertionResult HasHTMLStartTagAt(const Comment *C,
  311. size_t Idx,
  312. HTMLStartTagComment *&HST,
  313. StringRef TagName,
  314. StringRef AttrName,
  315. StringRef AttrValue) {
  316. ::testing::AssertionResult AR = HasHTMLStartTagAt(C, Idx, HST, TagName);
  317. if (!AR)
  318. return AR;
  319. if (HST->isSelfClosing())
  320. return ::testing::AssertionFailure()
  321. << "HTMLStartTagComment is self-closing";
  322. if (HST->getNumAttrs() != 1)
  323. return ::testing::AssertionFailure()
  324. << "HTMLStartTagComment has " << HST->getNumAttrs() << " attr(s), "
  325. "expected 1";
  326. StringRef ActualName = HST->getAttr(0).Name;
  327. if (ActualName != AttrName)
  328. return ::testing::AssertionFailure()
  329. << "HTMLStartTagComment has attr \"" << ActualName.str() << "\", "
  330. "expected \"" << AttrName.str() << "\"";
  331. StringRef ActualValue = HST->getAttr(0).Value;
  332. if (ActualValue != AttrValue)
  333. return ::testing::AssertionFailure()
  334. << "HTMLStartTagComment has attr value \"" << ActualValue.str() << "\", "
  335. "expected \"" << AttrValue.str() << "\"";
  336. return ::testing::AssertionSuccess();
  337. }
  338. ::testing::AssertionResult HasHTMLEndTagAt(const Comment *C,
  339. size_t Idx,
  340. HTMLEndTagComment *&HET,
  341. StringRef TagName) {
  342. ::testing::AssertionResult AR = GetChildAt(C, Idx, HET);
  343. if (!AR)
  344. return AR;
  345. StringRef ActualTagName = HET->getTagName();
  346. if (ActualTagName != TagName)
  347. return ::testing::AssertionFailure()
  348. << "HTMLEndTagComment has name \"" << ActualTagName.str() << "\", "
  349. "expected \"" << TagName.str() << "\"";
  350. return ::testing::AssertionSuccess();
  351. }
  352. ::testing::AssertionResult HasParagraphCommentAt(const Comment *C,
  353. size_t Idx,
  354. StringRef Text) {
  355. ParagraphComment *PC;
  356. {
  357. ::testing::AssertionResult AR = GetChildAt(C, Idx, PC);
  358. if (!AR)
  359. return AR;
  360. }
  361. {
  362. ::testing::AssertionResult AR = HasChildCount(PC, 1);
  363. if (!AR)
  364. return AR;
  365. }
  366. {
  367. ::testing::AssertionResult AR = HasTextAt(PC, 0, Text);
  368. if (!AR)
  369. return AR;
  370. }
  371. return ::testing::AssertionSuccess();
  372. }
  373. ::testing::AssertionResult HasVerbatimBlockAt(const Comment *C,
  374. const CommandTraits &Traits,
  375. size_t Idx,
  376. VerbatimBlockComment *&VBC,
  377. StringRef Name,
  378. StringRef CloseName) {
  379. ::testing::AssertionResult AR = GetChildAt(C, Idx, VBC);
  380. if (!AR)
  381. return AR;
  382. StringRef ActualName = VBC->getCommandName(Traits);
  383. if (ActualName != Name)
  384. return ::testing::AssertionFailure()
  385. << "VerbatimBlockComment has name \"" << ActualName.str() << "\", "
  386. "expected \"" << Name.str() << "\"";
  387. StringRef ActualCloseName = VBC->getCloseName();
  388. if (ActualCloseName != CloseName)
  389. return ::testing::AssertionFailure()
  390. << "VerbatimBlockComment has closing command name \""
  391. << ActualCloseName.str() << "\", "
  392. "expected \"" << CloseName.str() << "\"";
  393. return ::testing::AssertionSuccess();
  394. }
  395. struct NoLines {};
  396. struct Lines {};
  397. ::testing::AssertionResult HasVerbatimBlockAt(const Comment *C,
  398. const CommandTraits &Traits,
  399. size_t Idx,
  400. VerbatimBlockComment *&VBC,
  401. StringRef Name,
  402. StringRef CloseName,
  403. NoLines) {
  404. ::testing::AssertionResult AR = HasVerbatimBlockAt(C, Traits, Idx, VBC, Name,
  405. CloseName);
  406. if (!AR)
  407. return AR;
  408. if (VBC->getNumLines() != 0)
  409. return ::testing::AssertionFailure()
  410. << "VerbatimBlockComment has " << VBC->getNumLines() << " lines(s), "
  411. "expected 0";
  412. return ::testing::AssertionSuccess();
  413. }
  414. ::testing::AssertionResult HasVerbatimBlockAt(const Comment *C,
  415. const CommandTraits &Traits,
  416. size_t Idx,
  417. VerbatimBlockComment *&VBC,
  418. StringRef Name,
  419. StringRef CloseName,
  420. Lines,
  421. StringRef Line0) {
  422. ::testing::AssertionResult AR = HasVerbatimBlockAt(C, Traits, Idx, VBC, Name,
  423. CloseName);
  424. if (!AR)
  425. return AR;
  426. if (VBC->getNumLines() != 1)
  427. return ::testing::AssertionFailure()
  428. << "VerbatimBlockComment has " << VBC->getNumLines() << " lines(s), "
  429. "expected 1";
  430. StringRef ActualLine0 = VBC->getText(0);
  431. if (ActualLine0 != Line0)
  432. return ::testing::AssertionFailure()
  433. << "VerbatimBlockComment has lines[0] \"" << ActualLine0.str() << "\", "
  434. "expected \"" << Line0.str() << "\"";
  435. return ::testing::AssertionSuccess();
  436. }
  437. ::testing::AssertionResult HasVerbatimBlockAt(const Comment *C,
  438. const CommandTraits &Traits,
  439. size_t Idx,
  440. VerbatimBlockComment *&VBC,
  441. StringRef Name,
  442. StringRef CloseName,
  443. Lines,
  444. StringRef Line0,
  445. StringRef Line1) {
  446. ::testing::AssertionResult AR = HasVerbatimBlockAt(C, Traits, Idx, VBC, Name,
  447. CloseName);
  448. if (!AR)
  449. return AR;
  450. if (VBC->getNumLines() != 2)
  451. return ::testing::AssertionFailure()
  452. << "VerbatimBlockComment has " << VBC->getNumLines() << " lines(s), "
  453. "expected 2";
  454. StringRef ActualLine0 = VBC->getText(0);
  455. if (ActualLine0 != Line0)
  456. return ::testing::AssertionFailure()
  457. << "VerbatimBlockComment has lines[0] \"" << ActualLine0.str() << "\", "
  458. "expected \"" << Line0.str() << "\"";
  459. StringRef ActualLine1 = VBC->getText(1);
  460. if (ActualLine1 != Line1)
  461. return ::testing::AssertionFailure()
  462. << "VerbatimBlockComment has lines[1] \"" << ActualLine1.str() << "\", "
  463. "expected \"" << Line1.str() << "\"";
  464. return ::testing::AssertionSuccess();
  465. }
  466. ::testing::AssertionResult HasVerbatimLineAt(const Comment *C,
  467. const CommandTraits &Traits,
  468. size_t Idx,
  469. VerbatimLineComment *&VLC,
  470. StringRef Name,
  471. StringRef Text) {
  472. ::testing::AssertionResult AR = GetChildAt(C, Idx, VLC);
  473. if (!AR)
  474. return AR;
  475. StringRef ActualName = VLC->getCommandName(Traits);
  476. if (ActualName != Name)
  477. return ::testing::AssertionFailure()
  478. << "VerbatimLineComment has name \"" << ActualName.str() << "\", "
  479. "expected \"" << Name.str() << "\"";
  480. StringRef ActualText = VLC->getText();
  481. if (ActualText != Text)
  482. return ::testing::AssertionFailure()
  483. << "VerbatimLineComment has text \"" << ActualText.str() << "\", "
  484. "expected \"" << Text.str() << "\"";
  485. return ::testing::AssertionSuccess();
  486. }
  487. TEST_F(CommentParserTest, Basic1) {
  488. const char *Source = "//";
  489. FullComment *FC = parseString(Source);
  490. ASSERT_TRUE(HasChildCount(FC, 0));
  491. }
  492. TEST_F(CommentParserTest, Basic2) {
  493. const char *Source = "// Meow";
  494. FullComment *FC = parseString(Source);
  495. ASSERT_TRUE(HasChildCount(FC, 1));
  496. ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " Meow"));
  497. }
  498. TEST_F(CommentParserTest, Basic3) {
  499. const char *Source =
  500. "// Aaa\n"
  501. "// Bbb";
  502. FullComment *FC = parseString(Source);
  503. ASSERT_TRUE(HasChildCount(FC, 1));
  504. {
  505. ParagraphComment *PC;
  506. ASSERT_TRUE(GetChildAt(FC, 0, PC));
  507. ASSERT_TRUE(HasChildCount(PC, 2));
  508. ASSERT_TRUE(HasTextWithNewlineAt(PC, 0, " Aaa"));
  509. ASSERT_TRUE(HasTextAt(PC, 1, " Bbb"));
  510. }
  511. }
  512. TEST_F(CommentParserTest, ParagraphSplitting1) {
  513. const char *Sources[] = {
  514. "// Aaa\n"
  515. "//\n"
  516. "// Bbb",
  517. "// Aaa\n"
  518. "// \n"
  519. "// Bbb",
  520. "// Aaa\n"
  521. "//\t\n"
  522. "// Bbb",
  523. "// Aaa\n"
  524. "//\n"
  525. "//\n"
  526. "// Bbb",
  527. "/**\n"
  528. " Aaa\n"
  529. "\n"
  530. " Bbb\n"
  531. "*/",
  532. "/**\n"
  533. " Aaa\n"
  534. " \n"
  535. " Bbb\n"
  536. "*/",
  537. "/**\n"
  538. " Aaa\n"
  539. "\t \n"
  540. " Bbb\n"
  541. "*/",
  542. };
  543. for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
  544. FullComment *FC = parseString(Sources[i]);
  545. ASSERT_TRUE(HasChildCount(FC, 2));
  546. ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " Aaa"));
  547. ASSERT_TRUE(HasParagraphCommentAt(FC, 1, " Bbb"));
  548. }
  549. }
  550. TEST_F(CommentParserTest, Paragraph1) {
  551. const char *Source =
  552. "// \\brief Aaa\n"
  553. "//\n"
  554. "// Bbb";
  555. FullComment *FC = parseString(Source);
  556. ASSERT_TRUE(HasChildCount(FC, 3));
  557. ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
  558. {
  559. BlockCommandComment *BCC;
  560. ParagraphComment *PC;
  561. ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "brief", PC));
  562. ASSERT_TRUE(HasParagraphCommentAt(BCC, 0, " Aaa"));
  563. }
  564. ASSERT_TRUE(HasParagraphCommentAt(FC, 2, " Bbb"));
  565. }
  566. TEST_F(CommentParserTest, Paragraph2) {
  567. const char *Source = "// \\brief \\author";
  568. FullComment *FC = parseString(Source);
  569. ASSERT_TRUE(HasChildCount(FC, 3));
  570. ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
  571. {
  572. BlockCommandComment *BCC;
  573. ParagraphComment *PC;
  574. ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "brief", PC));
  575. ASSERT_TRUE(HasParagraphCommentAt(BCC, 0, " "));
  576. }
  577. {
  578. BlockCommandComment *BCC;
  579. ParagraphComment *PC;
  580. ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 2, BCC, "author", PC));
  581. ASSERT_TRUE(GetChildAt(BCC, 0, PC));
  582. ASSERT_TRUE(HasChildCount(PC, 0));
  583. }
  584. }
  585. TEST_F(CommentParserTest, Paragraph3) {
  586. const char *Source =
  587. "// \\brief Aaa\n"
  588. "// Bbb \\author\n"
  589. "// Ccc";
  590. FullComment *FC = parseString(Source);
  591. ASSERT_TRUE(HasChildCount(FC, 3));
  592. ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
  593. {
  594. BlockCommandComment *BCC;
  595. ParagraphComment *PC;
  596. ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "brief", PC));
  597. ASSERT_TRUE(GetChildAt(BCC, 0, PC));
  598. ASSERT_TRUE(HasChildCount(PC, 2));
  599. ASSERT_TRUE(HasTextWithNewlineAt(PC, 0, " Aaa"));
  600. ASSERT_TRUE(HasTextAt(PC, 1, " Bbb "));
  601. }
  602. {
  603. BlockCommandComment *BCC;
  604. ParagraphComment *PC;
  605. ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 2, BCC, "author", PC));
  606. ASSERT_TRUE(HasParagraphCommentAt(BCC, 0, " Ccc"));
  607. }
  608. }
  609. TEST_F(CommentParserTest, ParamCommand1) {
  610. const char *Source = "// \\param aaa";
  611. FullComment *FC = parseString(Source);
  612. ASSERT_TRUE(HasChildCount(FC, 2));
  613. ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
  614. {
  615. ParamCommandComment *PCC;
  616. ParagraphComment *PC;
  617. ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param",
  618. ParamCommandComment::In,
  619. /* IsDirectionExplicit = */ false,
  620. "aaa", PC));
  621. ASSERT_TRUE(HasChildCount(PCC, 1));
  622. ASSERT_TRUE(HasChildCount(PC, 0));
  623. }
  624. }
  625. TEST_F(CommentParserTest, ParamCommand2) {
  626. const char *Source = "// \\param\\brief";
  627. FullComment *FC = parseString(Source);
  628. ASSERT_TRUE(HasChildCount(FC, 3));
  629. ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
  630. {
  631. ParamCommandComment *PCC;
  632. ParagraphComment *PC;
  633. ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param",
  634. ParamCommandComment::In,
  635. /* IsDirectionExplicit = */ false,
  636. "", PC));
  637. ASSERT_TRUE(HasChildCount(PCC, 1));
  638. ASSERT_TRUE(HasChildCount(PC, 0));
  639. }
  640. {
  641. BlockCommandComment *BCC;
  642. ParagraphComment *PC;
  643. ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 2, BCC, "brief", PC));
  644. ASSERT_TRUE(HasChildCount(PC, 0));
  645. }
  646. }
  647. TEST_F(CommentParserTest, ParamCommand3) {
  648. const char *Sources[] = {
  649. "// \\param aaa Bbb\n",
  650. "// \\param\n"
  651. "// aaa Bbb\n",
  652. "// \\param \n"
  653. "// aaa Bbb\n",
  654. "// \\param aaa\n"
  655. "// Bbb\n"
  656. };
  657. for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
  658. FullComment *FC = parseString(Sources[i]);
  659. ASSERT_TRUE(HasChildCount(FC, 2));
  660. ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
  661. {
  662. ParamCommandComment *PCC;
  663. ParagraphComment *PC;
  664. ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param",
  665. ParamCommandComment::In,
  666. /* IsDirectionExplicit = */ false,
  667. "aaa", PC));
  668. ASSERT_TRUE(HasChildCount(PCC, 1));
  669. ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb"));
  670. }
  671. }
  672. }
  673. TEST_F(CommentParserTest, ParamCommand4) {
  674. const char *Sources[] = {
  675. "// \\param [in] aaa Bbb\n",
  676. "// \\param[in] aaa Bbb\n",
  677. "// \\param\n"
  678. "// [in] aaa Bbb\n",
  679. "// \\param [in]\n"
  680. "// aaa Bbb\n",
  681. "// \\param [in] aaa\n"
  682. "// Bbb\n",
  683. };
  684. for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
  685. FullComment *FC = parseString(Sources[i]);
  686. ASSERT_TRUE(HasChildCount(FC, 2));
  687. ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
  688. {
  689. ParamCommandComment *PCC;
  690. ParagraphComment *PC;
  691. ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param",
  692. ParamCommandComment::In,
  693. /* IsDirectionExplicit = */ true,
  694. "aaa", PC));
  695. ASSERT_TRUE(HasChildCount(PCC, 1));
  696. ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb"));
  697. }
  698. }
  699. }
  700. TEST_F(CommentParserTest, ParamCommand5) {
  701. const char *Sources[] = {
  702. "// \\param [out] aaa Bbb\n",
  703. "// \\param[out] aaa Bbb\n",
  704. "// \\param\n"
  705. "// [out] aaa Bbb\n",
  706. "// \\param [out]\n"
  707. "// aaa Bbb\n",
  708. "// \\param [out] aaa\n"
  709. "// Bbb\n",
  710. };
  711. for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
  712. FullComment *FC = parseString(Sources[i]);
  713. ASSERT_TRUE(HasChildCount(FC, 2));
  714. ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
  715. {
  716. ParamCommandComment *PCC;
  717. ParagraphComment *PC;
  718. ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param",
  719. ParamCommandComment::Out,
  720. /* IsDirectionExplicit = */ true,
  721. "aaa", PC));
  722. ASSERT_TRUE(HasChildCount(PCC, 1));
  723. ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb"));
  724. }
  725. }
  726. }
  727. TEST_F(CommentParserTest, ParamCommand6) {
  728. const char *Sources[] = {
  729. "// \\param [in,out] aaa Bbb\n",
  730. "// \\param[in,out] aaa Bbb\n",
  731. "// \\param [in, out] aaa Bbb\n",
  732. "// \\param [in,\n"
  733. "// out] aaa Bbb\n",
  734. "// \\param [in,out]\n"
  735. "// aaa Bbb\n",
  736. "// \\param [in,out] aaa\n"
  737. "// Bbb\n"
  738. };
  739. for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
  740. FullComment *FC = parseString(Sources[i]);
  741. ASSERT_TRUE(HasChildCount(FC, 2));
  742. ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
  743. {
  744. ParamCommandComment *PCC;
  745. ParagraphComment *PC;
  746. ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param",
  747. ParamCommandComment::InOut,
  748. /* IsDirectionExplicit = */ true,
  749. "aaa", PC));
  750. ASSERT_TRUE(HasChildCount(PCC, 1));
  751. ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb"));
  752. }
  753. }
  754. }
  755. TEST_F(CommentParserTest, ParamCommand7) {
  756. const char *Source =
  757. "// \\param aaa \\% Bbb \\$ ccc\n";
  758. FullComment *FC = parseString(Source);
  759. ASSERT_TRUE(HasChildCount(FC, 2));
  760. ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
  761. {
  762. ParamCommandComment *PCC;
  763. ParagraphComment *PC;
  764. ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param",
  765. ParamCommandComment::In,
  766. /* IsDirectionExplicit = */ false,
  767. "aaa", PC));
  768. ASSERT_TRUE(HasChildCount(PCC, 1));
  769. ASSERT_TRUE(HasChildCount(PC, 5));
  770. ASSERT_TRUE(HasTextAt(PC, 0, " "));
  771. ASSERT_TRUE(HasTextAt(PC, 1, "%"));
  772. ASSERT_TRUE(HasTextAt(PC, 2, " Bbb "));
  773. ASSERT_TRUE(HasTextAt(PC, 3, "$"));
  774. ASSERT_TRUE(HasTextAt(PC, 4, " ccc"));
  775. }
  776. }
  777. TEST_F(CommentParserTest, TParamCommand1) {
  778. const char *Sources[] = {
  779. "// \\tparam aaa Bbb\n",
  780. "// \\tparam\n"
  781. "// aaa Bbb\n",
  782. "// \\tparam \n"
  783. "// aaa Bbb\n",
  784. "// \\tparam aaa\n"
  785. "// Bbb\n"
  786. };
  787. for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
  788. FullComment *FC = parseString(Sources[i]);
  789. ASSERT_TRUE(HasChildCount(FC, 2));
  790. ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
  791. {
  792. TParamCommandComment *TPCC;
  793. ParagraphComment *PC;
  794. ASSERT_TRUE(HasTParamCommandAt(FC, Traits, 1, TPCC, "tparam",
  795. "aaa", PC));
  796. ASSERT_TRUE(HasChildCount(TPCC, 1));
  797. ASSERT_TRUE(HasParagraphCommentAt(TPCC, 0, " Bbb"));
  798. }
  799. }
  800. }
  801. TEST_F(CommentParserTest, TParamCommand2) {
  802. const char *Source = "// \\tparam\\brief";
  803. FullComment *FC = parseString(Source);
  804. ASSERT_TRUE(HasChildCount(FC, 3));
  805. ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
  806. {
  807. TParamCommandComment *TPCC;
  808. ParagraphComment *PC;
  809. ASSERT_TRUE(HasTParamCommandAt(FC, Traits, 1, TPCC, "tparam", "", PC));
  810. ASSERT_TRUE(HasChildCount(TPCC, 1));
  811. ASSERT_TRUE(HasChildCount(PC, 0));
  812. }
  813. {
  814. BlockCommandComment *BCC;
  815. ParagraphComment *PC;
  816. ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 2, BCC, "brief", PC));
  817. ASSERT_TRUE(HasChildCount(PC, 0));
  818. }
  819. }
  820. TEST_F(CommentParserTest, InlineCommand1) {
  821. const char *Source = "// \\c";
  822. FullComment *FC = parseString(Source);
  823. ASSERT_TRUE(HasChildCount(FC, 1));
  824. {
  825. ParagraphComment *PC;
  826. InlineCommandComment *ICC;
  827. ASSERT_TRUE(GetChildAt(FC, 0, PC));
  828. ASSERT_TRUE(HasChildCount(PC, 2));
  829. ASSERT_TRUE(HasTextAt(PC, 0, " "));
  830. ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "c", NoArgs()));
  831. }
  832. }
  833. TEST_F(CommentParserTest, InlineCommand2) {
  834. const char *Source = "// \\c ";
  835. FullComment *FC = parseString(Source);
  836. ASSERT_TRUE(HasChildCount(FC, 1));
  837. {
  838. ParagraphComment *PC;
  839. InlineCommandComment *ICC;
  840. ASSERT_TRUE(GetChildAt(FC, 0, PC));
  841. ASSERT_TRUE(HasChildCount(PC, 3));
  842. ASSERT_TRUE(HasTextAt(PC, 0, " "));
  843. ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "c", NoArgs()));
  844. ASSERT_TRUE(HasTextAt(PC, 2, " "));
  845. }
  846. }
  847. TEST_F(CommentParserTest, InlineCommand3) {
  848. const char *Source = "// \\c aaa\n";
  849. FullComment *FC = parseString(Source);
  850. ASSERT_TRUE(HasChildCount(FC, 1));
  851. {
  852. ParagraphComment *PC;
  853. InlineCommandComment *ICC;
  854. ASSERT_TRUE(GetChildAt(FC, 0, PC));
  855. ASSERT_TRUE(HasChildCount(PC, 2));
  856. ASSERT_TRUE(HasTextAt(PC, 0, " "));
  857. ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "c", "aaa"));
  858. }
  859. }
  860. TEST_F(CommentParserTest, InlineCommand4) {
  861. const char *Source = "// \\c aaa bbb";
  862. FullComment *FC = parseString(Source);
  863. ASSERT_TRUE(HasChildCount(FC, 1));
  864. {
  865. ParagraphComment *PC;
  866. InlineCommandComment *ICC;
  867. ASSERT_TRUE(GetChildAt(FC, 0, PC));
  868. ASSERT_TRUE(HasChildCount(PC, 3));
  869. ASSERT_TRUE(HasTextAt(PC, 0, " "));
  870. ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "c", "aaa"));
  871. ASSERT_TRUE(HasTextAt(PC, 2, " bbb"));
  872. }
  873. }
  874. TEST_F(CommentParserTest, InlineCommand5) {
  875. const char *Source = "// \\unknown aaa\n";
  876. FullComment *FC = parseString(Source);
  877. ASSERT_TRUE(HasChildCount(FC, 1));
  878. {
  879. ParagraphComment *PC;
  880. InlineCommandComment *ICC;
  881. ASSERT_TRUE(GetChildAt(FC, 0, PC));
  882. ASSERT_TRUE(HasChildCount(PC, 3));
  883. ASSERT_TRUE(HasTextAt(PC, 0, " "));
  884. ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "unknown", NoArgs()));
  885. ASSERT_TRUE(HasTextAt(PC, 2, " aaa"));
  886. }
  887. }
  888. TEST_F(CommentParserTest, HTML1) {
  889. const char *Sources[] = {
  890. "// <a",
  891. "// <a>",
  892. "// <a >"
  893. };
  894. for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
  895. FullComment *FC = parseString(Sources[i]);
  896. ASSERT_TRUE(HasChildCount(FC, 1));
  897. {
  898. ParagraphComment *PC;
  899. HTMLStartTagComment *HST;
  900. ASSERT_TRUE(GetChildAt(FC, 0, PC));
  901. ASSERT_TRUE(HasChildCount(PC, 2));
  902. ASSERT_TRUE(HasTextAt(PC, 0, " "));
  903. ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "a", NoAttrs()));
  904. }
  905. }
  906. }
  907. TEST_F(CommentParserTest, HTML2) {
  908. const char *Sources[] = {
  909. "// <br/>",
  910. "// <br />"
  911. };
  912. for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
  913. FullComment *FC = parseString(Sources[i]);
  914. ASSERT_TRUE(HasChildCount(FC, 1));
  915. {
  916. ParagraphComment *PC;
  917. HTMLStartTagComment *HST;
  918. ASSERT_TRUE(GetChildAt(FC, 0, PC));
  919. ASSERT_TRUE(HasChildCount(PC, 2));
  920. ASSERT_TRUE(HasTextAt(PC, 0, " "));
  921. ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "br", SelfClosing()));
  922. }
  923. }
  924. }
  925. TEST_F(CommentParserTest, HTML3) {
  926. const char *Sources[] = {
  927. "// <a href",
  928. "// <a href ",
  929. "// <a href>",
  930. "// <a href >",
  931. };
  932. for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
  933. FullComment *FC = parseString(Sources[i]);
  934. ASSERT_TRUE(HasChildCount(FC, 1));
  935. {
  936. ParagraphComment *PC;
  937. HTMLStartTagComment *HST;
  938. ASSERT_TRUE(GetChildAt(FC, 0, PC));
  939. ASSERT_TRUE(HasChildCount(PC, 2));
  940. ASSERT_TRUE(HasTextAt(PC, 0, " "));
  941. ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "a", "href", ""));
  942. }
  943. }
  944. }
  945. TEST_F(CommentParserTest, HTML4) {
  946. const char *Sources[] = {
  947. "// <a href=\"bbb\"",
  948. "// <a href=\"bbb\">",
  949. };
  950. for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
  951. FullComment *FC = parseString(Sources[i]);
  952. ASSERT_TRUE(HasChildCount(FC, 1));
  953. {
  954. ParagraphComment *PC;
  955. HTMLStartTagComment *HST;
  956. ASSERT_TRUE(GetChildAt(FC, 0, PC));
  957. ASSERT_TRUE(HasChildCount(PC, 2));
  958. ASSERT_TRUE(HasTextAt(PC, 0, " "));
  959. ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "a", "href", "bbb"));
  960. }
  961. }
  962. }
  963. TEST_F(CommentParserTest, HTML5) {
  964. const char *Sources[] = {
  965. "// </a",
  966. "// </a>",
  967. "// </a >"
  968. };
  969. for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
  970. FullComment *FC = parseString(Sources[i]);
  971. ASSERT_TRUE(HasChildCount(FC, 1));
  972. {
  973. ParagraphComment *PC;
  974. HTMLEndTagComment *HET;
  975. ASSERT_TRUE(GetChildAt(FC, 0, PC));
  976. ASSERT_TRUE(HasChildCount(PC, 2));
  977. ASSERT_TRUE(HasTextAt(PC, 0, " "));
  978. ASSERT_TRUE(HasHTMLEndTagAt(PC, 1, HET, "a"));
  979. }
  980. }
  981. }
  982. TEST_F(CommentParserTest, HTML6) {
  983. const char *Source =
  984. "// <pre>\n"
  985. "// Aaa\n"
  986. "// Bbb\n"
  987. "// </pre>\n";
  988. FullComment *FC = parseString(Source);
  989. ASSERT_TRUE(HasChildCount(FC, 1));
  990. {
  991. ParagraphComment *PC;
  992. HTMLStartTagComment *HST;
  993. HTMLEndTagComment *HET;
  994. ASSERT_TRUE(GetChildAt(FC, 0, PC));
  995. ASSERT_TRUE(HasChildCount(PC, 6));
  996. ASSERT_TRUE(HasTextAt(PC, 0, " "));
  997. ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "pre", NoAttrs()));
  998. ASSERT_TRUE(HasTextWithNewlineAt(PC, 2, " Aaa"));
  999. ASSERT_TRUE(HasTextWithNewlineAt(PC, 3, " Bbb"));
  1000. ASSERT_TRUE(HasTextAt(PC, 4, " "));
  1001. ASSERT_TRUE(HasHTMLEndTagAt(PC, 5, HET, "pre"));
  1002. }
  1003. }
  1004. TEST_F(CommentParserTest, VerbatimBlock1) {
  1005. const char *Source = "// \\verbatim\\endverbatim\n";
  1006. FullComment *FC = parseString(Source);
  1007. ASSERT_TRUE(HasChildCount(FC, 2));
  1008. ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
  1009. {
  1010. VerbatimBlockComment *VCC;
  1011. ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VCC,
  1012. "verbatim", "endverbatim",
  1013. NoLines()));
  1014. }
  1015. }
  1016. TEST_F(CommentParserTest, VerbatimBlock2) {
  1017. const char *Source = "// \\verbatim Aaa \\endverbatim\n";
  1018. FullComment *FC = parseString(Source);
  1019. ASSERT_TRUE(HasChildCount(FC, 2));
  1020. ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
  1021. {
  1022. VerbatimBlockComment *VBC;
  1023. ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC,
  1024. "verbatim", "endverbatim",
  1025. Lines(), " Aaa "));
  1026. }
  1027. }
  1028. TEST_F(CommentParserTest, VerbatimBlock3) {
  1029. const char *Source = "// \\verbatim Aaa\n";
  1030. FullComment *FC = parseString(Source);
  1031. ASSERT_TRUE(HasChildCount(FC, 2));
  1032. ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
  1033. {
  1034. VerbatimBlockComment *VBC;
  1035. ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC, "verbatim", "",
  1036. Lines(), " Aaa"));
  1037. }
  1038. }
  1039. TEST_F(CommentParserTest, VerbatimBlock4) {
  1040. const char *Source =
  1041. "//\\verbatim\n"
  1042. "//\\endverbatim\n";
  1043. FullComment *FC = parseString(Source);
  1044. ASSERT_TRUE(HasChildCount(FC, 1));
  1045. {
  1046. VerbatimBlockComment *VBC;
  1047. ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 0, VBC,
  1048. "verbatim", "endverbatim",
  1049. NoLines()));
  1050. }
  1051. }
  1052. TEST_F(CommentParserTest, VerbatimBlock5) {
  1053. const char *Sources[] = {
  1054. "//\\verbatim\n"
  1055. "// Aaa\n"
  1056. "//\\endverbatim\n",
  1057. "/*\\verbatim\n"
  1058. " * Aaa\n"
  1059. " *\\endverbatim*/"
  1060. };
  1061. for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
  1062. FullComment *FC = parseString(Sources[i]);
  1063. ASSERT_TRUE(HasChildCount(FC, 1));
  1064. {
  1065. VerbatimBlockComment *VBC;
  1066. ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 0, VBC,
  1067. "verbatim", "endverbatim",
  1068. Lines(), " Aaa"));
  1069. }
  1070. }
  1071. }
  1072. TEST_F(CommentParserTest, VerbatimBlock6) {
  1073. const char *Sources[] = {
  1074. "// \\verbatim\n"
  1075. "// Aaa\n"
  1076. "// \\endverbatim\n",
  1077. "/* \\verbatim\n"
  1078. " * Aaa\n"
  1079. " * \\endverbatim*/"
  1080. };
  1081. for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
  1082. FullComment *FC = parseString(Sources[i]);
  1083. ASSERT_TRUE(HasChildCount(FC, 2));
  1084. ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
  1085. {
  1086. VerbatimBlockComment *VBC;
  1087. ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC,
  1088. "verbatim", "endverbatim",
  1089. Lines(), " Aaa"));
  1090. }
  1091. }
  1092. }
  1093. TEST_F(CommentParserTest, VerbatimBlock7) {
  1094. const char *Sources[] = {
  1095. "// \\verbatim\n"
  1096. "// Aaa\n"
  1097. "// Bbb\n"
  1098. "// \\endverbatim\n",
  1099. "/* \\verbatim\n"
  1100. " * Aaa\n"
  1101. " * Bbb\n"
  1102. " * \\endverbatim*/"
  1103. };
  1104. for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
  1105. FullComment *FC = parseString(Sources[i]);
  1106. ASSERT_TRUE(HasChildCount(FC, 2));
  1107. ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
  1108. {
  1109. VerbatimBlockComment *VBC;
  1110. ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC,
  1111. "verbatim", "endverbatim",
  1112. Lines(), " Aaa", " Bbb"));
  1113. }
  1114. }
  1115. }
  1116. TEST_F(CommentParserTest, VerbatimBlock8) {
  1117. const char *Sources[] = {
  1118. "// \\verbatim\n"
  1119. "// Aaa\n"
  1120. "//\n"
  1121. "// Bbb\n"
  1122. "// \\endverbatim\n",
  1123. "/* \\verbatim\n"
  1124. " * Aaa\n"
  1125. " *\n"
  1126. " * Bbb\n"
  1127. " * \\endverbatim*/"
  1128. };
  1129. for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
  1130. FullComment *FC = parseString(Sources[i]);
  1131. ASSERT_TRUE(HasChildCount(FC, 2));
  1132. ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
  1133. {
  1134. VerbatimBlockComment *VBC;
  1135. ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC,
  1136. "verbatim", "endverbatim"));
  1137. ASSERT_EQ(3U, VBC->getNumLines());
  1138. ASSERT_EQ(" Aaa", VBC->getText(0));
  1139. ASSERT_EQ("", VBC->getText(1));
  1140. ASSERT_EQ(" Bbb", VBC->getText(2));
  1141. }
  1142. }
  1143. }
  1144. TEST_F(CommentParserTest, VerbatimLine1) {
  1145. const char *Sources[] = {
  1146. "// \\fn",
  1147. "// \\fn\n"
  1148. };
  1149. for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
  1150. FullComment *FC = parseString(Sources[i]);
  1151. ASSERT_TRUE(HasChildCount(FC, 2));
  1152. ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
  1153. {
  1154. VerbatimLineComment *VLC;
  1155. ASSERT_TRUE(HasVerbatimLineAt(FC, Traits, 1, VLC, "fn", ""));
  1156. }
  1157. }
  1158. }
  1159. TEST_F(CommentParserTest, VerbatimLine2) {
  1160. const char *Sources[] = {
  1161. "/// \\fn void *foo(const char *zzz = \"\\$\");\n//",
  1162. "/** \\fn void *foo(const char *zzz = \"\\$\");*/"
  1163. };
  1164. for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
  1165. FullComment *FC = parseString(Sources[i]);
  1166. ASSERT_TRUE(HasChildCount(FC, 2));
  1167. ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
  1168. {
  1169. VerbatimLineComment *VLC;
  1170. ASSERT_TRUE(HasVerbatimLineAt(FC, Traits, 1, VLC, "fn",
  1171. " void *foo(const char *zzz = \"\\$\");"));
  1172. }
  1173. }
  1174. }
  1175. TEST_F(CommentParserTest, Deprecated) {
  1176. const char *Sources[] = {
  1177. "/** @deprecated*/",
  1178. "/// @deprecated\n"
  1179. };
  1180. for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
  1181. FullComment *FC = parseString(Sources[i]);
  1182. ASSERT_TRUE(HasChildCount(FC, 2));
  1183. ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
  1184. {
  1185. BlockCommandComment *BCC;
  1186. ParagraphComment *PC;
  1187. ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "deprecated", PC));
  1188. ASSERT_TRUE(HasChildCount(PC, 0));
  1189. }
  1190. }
  1191. }
  1192. } // unnamed namespace
  1193. } // end namespace comments
  1194. } // end namespace clang