brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.0 KiB · bf9e179 Raw
145 lines · cpp
1//===--- CommentBriefParser.cpp - Dumb comment parser ---------------------===//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "clang/AST/CommentBriefParser.h"10#include "clang/AST/CommentCommandTraits.h"11#include "clang/Basic/CharInfo.h"12 13namespace clang {14namespace comments {15 16namespace {17 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 (clang::isWhitespace(C)) {27      if (!PrevWasSpace) {28        *O++ = ' ';29        PrevWasSpace = true;30      }31    } else {32      *O++ = C;33      PrevWasSpace = false;34    }35  }36  if (O != S.begin() && *(O - 1) == ' ')37    --O;38 39  S.resize(O - S.begin());40}41 42bool isWhitespace(StringRef Text) {43  return llvm::all_of(Text, clang::isWhitespace);44}45} // unnamed namespace46 47BriefParser::BriefParser(Lexer &L, const CommandTraits &Traits) :48    L(L), Traits(Traits) {49  // Get lookahead token.50  ConsumeToken();51}52 53std::string BriefParser::Parse() {54  std::string FirstParagraphOrBrief;55  std::string ReturnsParagraph;56  bool InFirstParagraph = true;57  bool InBrief = false;58  bool InReturns = false;59 60  while (Tok.isNot(tok::eof)) {61    if (Tok.is(tok::text)) {62      if (InFirstParagraph || InBrief)63        FirstParagraphOrBrief += Tok.getText();64      else if (InReturns)65        ReturnsParagraph += Tok.getText();66      ConsumeToken();67      continue;68    }69 70    if (Tok.is(tok::backslash_command) || Tok.is(tok::at_command)) {71      const CommandInfo *Info = Traits.getCommandInfo(Tok.getCommandID());72      if (Info->IsBriefCommand) {73        FirstParagraphOrBrief.clear();74        InBrief = true;75        ConsumeToken();76        continue;77      }78      if (Info->IsReturnsCommand) {79        InReturns = true;80        InBrief = false;81        InFirstParagraph = false;82        ReturnsParagraph += "Returns ";83        ConsumeToken();84        continue;85      }86      // Block commands implicitly start a new paragraph.87      if (Info->IsBlockCommand) {88        // We found an implicit paragraph end.89        InFirstParagraph = false;90        if (InBrief)91          break;92      }93    }94 95    if (Tok.is(tok::newline)) {96      if (InFirstParagraph || InBrief)97        FirstParagraphOrBrief += ' ';98      else if (InReturns)99        ReturnsParagraph += ' ';100      ConsumeToken();101 102      // If the next token is a whitespace only text, ignore it.  Thus we allow103      // two paragraphs to be separated by line that has only whitespace in it.104      //105      // We don't need to add a space to the parsed text because we just added106      // a space for the newline.107      if (Tok.is(tok::text)) {108        if (isWhitespace(Tok.getText()))109          ConsumeToken();110      }111 112      if (Tok.is(tok::newline)) {113        ConsumeToken();114        // We found a paragraph end.  This ends the brief description if115        // \command or its equivalent was explicitly used.116        // Stop scanning text because an explicit \paragraph is the117        // preferred one.118        if (InBrief)119          break;120        // End first paragraph if we found some non-whitespace text.121        if (InFirstParagraph && !isWhitespace(FirstParagraphOrBrief))122          InFirstParagraph = false;123        // End the \\returns paragraph because we found the paragraph end.124        InReturns = false;125      }126      continue;127    }128 129    // We didn't handle this token, so just drop it.130    ConsumeToken();131  }132 133  cleanupBrief(FirstParagraphOrBrief);134  if (!FirstParagraphOrBrief.empty())135    return FirstParagraphOrBrief;136 137  cleanupBrief(ReturnsParagraph);138  return ReturnsParagraph;139}140 141} // end namespace comments142} // end namespace clang143 144 145