//===--- RawCommentList.cpp - Processing raw comments -----------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/RawCommentList.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/CommentLexer.h"
#include "clang/AST/CommentBriefParser.h"
#include "llvm/ADT/STLExtras.h"

using namespace clang;

namespace {
/// Get comment kind and bool describing if it is a trailing comment.
std::pair<RawComment::CommentKind, bool> getCommentKind(StringRef Comment) {
  if (Comment.size() < 3 || Comment[0] != '/')
    return std::make_pair(RawComment::CK_Invalid, false);

  RawComment::CommentKind K;
  if (Comment[1] == '/') {
    if (Comment.size() < 3)
      return std::make_pair(RawComment::CK_OrdinaryBCPL, false);

    if (Comment[2] == '/')
      K = RawComment::CK_BCPLSlash;
    else if (Comment[2] == '!')
      K = RawComment::CK_BCPLExcl;
    else
      return std::make_pair(RawComment::CK_OrdinaryBCPL, false);
  } else {
    assert(Comment.size() >= 4);

    // Comment lexer does not understand escapes in comment markers, so pretend
    // that this is not a comment.
    if (Comment[1] != '*' ||
        Comment[Comment.size() - 2] != '*' ||
        Comment[Comment.size() - 1] != '/')
      return std::make_pair(RawComment::CK_Invalid, false);

    if (Comment[2] == '*')
      K = RawComment::CK_JavaDoc;
    else if (Comment[2] == '!')
      K = RawComment::CK_Qt;
    else
      return std::make_pair(RawComment::CK_OrdinaryC, false);
  }
  const bool TrailingComment = (Comment.size() > 3) && (Comment[3] == '<');
  return std::make_pair(K, TrailingComment);
}

bool mergedCommentIsTrailingComment(StringRef Comment) {
  return (Comment.size() > 3) && (Comment[3] == '<');
}
} // unnamed namespace

RawComment::RawComment(const SourceManager &SourceMgr, SourceRange SR,
                       bool Merged) :
    Range(SR), RawTextValid(false), BriefTextValid(false),
    IsAlmostTrailingComment(false),
    BeginLineValid(false), EndLineValid(false) {
  // Extract raw comment text, if possible.
  if (SR.getBegin() == SR.getEnd() || getRawText(SourceMgr).empty()) {
    Kind = CK_Invalid;
    return;
  }

  if (!Merged) {
    // Guess comment kind.
    std::pair<CommentKind, bool> K = getCommentKind(RawText);
    Kind = K.first;
    IsTrailingComment = K.second;

    IsAlmostTrailingComment = RawText.startswith("//<") ||
                                 RawText.startswith("/*<");
  } else {
    Kind = CK_Merged;
    IsTrailingComment = mergedCommentIsTrailingComment(RawText);
  }
}

unsigned RawComment::getBeginLine(const SourceManager &SM) const {
  if (BeginLineValid)
    return BeginLine;

  std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Range.getBegin());
  BeginLine = SM.getLineNumber(LocInfo.first, LocInfo.second);
  BeginLineValid = true;
  return BeginLine;
}

unsigned RawComment::getEndLine(const SourceManager &SM) const {
  if (EndLineValid)
    return EndLine;

  std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Range.getEnd());
  EndLine = SM.getLineNumber(LocInfo.first, LocInfo.second);
  EndLineValid = true;
  return EndLine;
}

StringRef RawComment::getRawTextSlow(const SourceManager &SourceMgr) const {
  FileID BeginFileID;
  FileID EndFileID;
  unsigned BeginOffset;
  unsigned EndOffset;

  llvm::tie(BeginFileID, BeginOffset) =
      SourceMgr.getDecomposedLoc(Range.getBegin());
  llvm::tie(EndFileID, EndOffset) =
      SourceMgr.getDecomposedLoc(Range.getEnd());

  const unsigned Length = EndOffset - BeginOffset;
  if (Length < 2)
    return StringRef();

  // The comment can't begin in one file and end in another.
  assert(BeginFileID == EndFileID);

  bool Invalid = false;
  const char *BufferStart = SourceMgr.getBufferData(BeginFileID,
                                                    &Invalid).data();
  if (Invalid)
    return StringRef();

  return StringRef(BufferStart + BeginOffset, Length);
}

StringRef RawComment::extractBriefText(const ASTContext &Context) const {
  // Make sure that RawText is valid.
  getRawText(Context.getSourceManager());

  comments::Lexer L(Range.getBegin(), comments::CommentOptions(),
                    RawText.begin(), RawText.end());
  comments::BriefParser P(L);

  const std::string Result = P.Parse();
  const unsigned BriefTextLength = Result.size();
  char *BriefTextPtr = new (Context) char[BriefTextLength + 1];
  memcpy(BriefTextPtr, Result.c_str(), BriefTextLength + 1);
  BriefText = StringRef(BriefTextPtr, BriefTextLength);
  BriefTextValid = true;

  return BriefText;
}

namespace {
bool containsOnlyWhitespace(StringRef Str) {
  return Str.find_first_not_of(" \t\f\v\r\n") == StringRef::npos;
}

bool onlyWhitespaceBetweenComments(SourceManager &SM,
                                   const RawComment &C1, const RawComment &C2) {
  std::pair<FileID, unsigned> C1EndLocInfo = SM.getDecomposedLoc(
                                                C1.getSourceRange().getEnd());
  std::pair<FileID, unsigned> C2BeginLocInfo = SM.getDecomposedLoc(
                                              C2.getSourceRange().getBegin());

  // Question does not make sense if comments are located in different files.
  if (C1EndLocInfo.first != C2BeginLocInfo.first)
    return false;

  bool Invalid = false;
  const char *Buffer = SM.getBufferData(C1EndLocInfo.first, &Invalid).data();
  if (Invalid)
    return false;

  StringRef TextBetweenComments(Buffer + C1EndLocInfo.second,
                                C2BeginLocInfo.second - C1EndLocInfo.second);

  return containsOnlyWhitespace(TextBetweenComments);
}
} // unnamed namespace

void RawCommentList::addComment(const RawComment &RC) {
  if (RC.isInvalid())
    return;

  // Check if the comments are not in source order.
  while (!Comments.empty() &&
         !SourceMgr.isBeforeInTranslationUnit(
              Comments.back().getSourceRange().getBegin(),
              RC.getSourceRange().getBegin())) {
    // If they are, just pop a few last comments that don't fit.
    // This happens if an \#include directive contains comments.
    Comments.pop_back();
  }

  if (OnlyWhitespaceSeen) {
    if (!onlyWhitespaceBetweenComments(SourceMgr, LastComment, RC))
      OnlyWhitespaceSeen = false;
  }

  LastComment = RC;

  // Ordinary comments are not interesting for us.
  if (RC.isOrdinary())
    return;

  // If this is the first Doxygen comment, save it (because there isn't
  // anything to merge it with).
  if (Comments.empty()) {
    Comments.push_back(RC);
    OnlyWhitespaceSeen = true;
    return;
  }

  const RawComment &C1 = Comments.back();
  const RawComment &C2 = RC;

  // Merge comments only if there is only whitespace between them.
  // Can't merge trailing and non-trailing comments.
  // Merge trailing comments if they are on same or consecutive lines.
  if (OnlyWhitespaceSeen &&
      (C1.isTrailingComment() == C2.isTrailingComment()) &&
      (!C1.isTrailingComment() ||
       C1.getEndLine(SourceMgr) + 1 >= C2.getBeginLine(SourceMgr))) {
    SourceRange MergedRange(C1.getSourceRange().getBegin(),
                            C2.getSourceRange().getEnd());
    RawComment Merged(SourceMgr, MergedRange, true);
    Comments.pop_back();
    Comments.push_back(Merged);
  } else
    Comments.push_back(RC);

  OnlyWhitespaceSeen = true;
}

