Path: blob/main/contrib/llvm-project/clang/lib/AST/CommentBriefParser.cpp
35260 views
//===--- CommentBriefParser.cpp - Dumb comment parser ---------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "clang/AST/CommentBriefParser.h"9#include "clang/AST/CommentCommandTraits.h"10#include "clang/Basic/CharInfo.h"1112namespace clang {13namespace comments {1415namespace {1617/// Convert all whitespace into spaces, remove leading and trailing spaces,18/// compress multiple spaces into one.19void cleanupBrief(std::string &S) {20bool PrevWasSpace = true;21std::string::iterator O = S.begin();22for (std::string::iterator I = S.begin(), E = S.end();23I != E; ++I) {24const char C = *I;25if (clang::isWhitespace(C)) {26if (!PrevWasSpace) {27*O++ = ' ';28PrevWasSpace = true;29}30} else {31*O++ = C;32PrevWasSpace = false;33}34}35if (O != S.begin() && *(O - 1) == ' ')36--O;3738S.resize(O - S.begin());39}4041bool isWhitespace(StringRef Text) {42return llvm::all_of(Text, clang::isWhitespace);43}44} // unnamed namespace4546BriefParser::BriefParser(Lexer &L, const CommandTraits &Traits) :47L(L), Traits(Traits) {48// Get lookahead token.49ConsumeToken();50}5152std::string BriefParser::Parse() {53std::string FirstParagraphOrBrief;54std::string ReturnsParagraph;55bool InFirstParagraph = true;56bool InBrief = false;57bool InReturns = false;5859while (Tok.isNot(tok::eof)) {60if (Tok.is(tok::text)) {61if (InFirstParagraph || InBrief)62FirstParagraphOrBrief += Tok.getText();63else if (InReturns)64ReturnsParagraph += Tok.getText();65ConsumeToken();66continue;67}6869if (Tok.is(tok::backslash_command) || Tok.is(tok::at_command)) {70const CommandInfo *Info = Traits.getCommandInfo(Tok.getCommandID());71if (Info->IsBriefCommand) {72FirstParagraphOrBrief.clear();73InBrief = true;74ConsumeToken();75continue;76}77if (Info->IsReturnsCommand) {78InReturns = true;79InBrief = false;80InFirstParagraph = false;81ReturnsParagraph += "Returns ";82ConsumeToken();83continue;84}85// Block commands implicitly start a new paragraph.86if (Info->IsBlockCommand) {87// We found an implicit paragraph end.88InFirstParagraph = false;89if (InBrief)90break;91}92}9394if (Tok.is(tok::newline)) {95if (InFirstParagraph || InBrief)96FirstParagraphOrBrief += ' ';97else if (InReturns)98ReturnsParagraph += ' ';99ConsumeToken();100101// If the next token is a whitespace only text, ignore it. Thus we allow102// two paragraphs to be separated by line that has only whitespace in it.103//104// We don't need to add a space to the parsed text because we just added105// a space for the newline.106if (Tok.is(tok::text)) {107if (isWhitespace(Tok.getText()))108ConsumeToken();109}110111if (Tok.is(tok::newline)) {112ConsumeToken();113// We found a paragraph end. This ends the brief description if114// \command or its equivalent was explicitly used.115// Stop scanning text because an explicit \paragraph is the116// preferred one.117if (InBrief)118break;119// End first paragraph if we found some non-whitespace text.120if (InFirstParagraph && !isWhitespace(FirstParagraphOrBrief))121InFirstParagraph = false;122// End the \\returns paragraph because we found the paragraph end.123InReturns = false;124}125continue;126}127128// We didn't handle this token, so just drop it.129ConsumeToken();130}131132cleanupBrief(FirstParagraphOrBrief);133if (!FirstParagraphOrBrief.empty())134return FirstParagraphOrBrief;135136cleanupBrief(ReturnsParagraph);137return ReturnsParagraph;138}139140} // end namespace comments141} // end namespace clang142143144145146