//===--- WhitespaceManager.cpp - Format C++ code --------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief This file implements WhitespaceManager class.
///
//===----------------------------------------------------------------------===//

#include "WhitespaceManager.h"
#include "llvm/ADT/STLExtras.h"

namespace clang {
namespace format {

bool
WhitespaceManager::Change::IsBeforeInFile::operator()(const Change &C1,
                                                      const Change &C2) const {
  return SourceMgr.isBeforeInTranslationUnit(
      C1.OriginalWhitespaceRange.getBegin(),
      C2.OriginalWhitespaceRange.getBegin());
}

WhitespaceManager::Change::Change(
    bool CreateReplacement, const SourceRange &OriginalWhitespaceRange,
    unsigned Spaces, unsigned StartOfTokenColumn, unsigned NewlinesBefore,
    StringRef PreviousLinePostfix, StringRef CurrentLinePrefix,
    tok::TokenKind Kind, bool ContinuesPPDirective)
    : CreateReplacement(CreateReplacement),
      OriginalWhitespaceRange(OriginalWhitespaceRange),
      StartOfTokenColumn(StartOfTokenColumn), NewlinesBefore(NewlinesBefore),
      PreviousLinePostfix(PreviousLinePostfix),
      CurrentLinePrefix(CurrentLinePrefix), Kind(Kind),
      ContinuesPPDirective(ContinuesPPDirective), Spaces(Spaces) {}

void WhitespaceManager::replaceWhitespace(const FormatToken &Tok,
                                          unsigned Newlines, unsigned Spaces,
                                          unsigned StartOfTokenColumn,
                                          bool InPPDirective) {
  Changes.push_back(Change(true, Tok.WhitespaceRange, Spaces,
                           StartOfTokenColumn, Newlines, "", "",
                           Tok.Tok.getKind(), InPPDirective && !Tok.IsFirst));
}

void WhitespaceManager::addUntouchableToken(const FormatToken &Tok,
                                            bool InPPDirective) {
  Changes.push_back(
      Change(false, Tok.WhitespaceRange, /*Spaces=*/0,
             SourceMgr.getSpellingColumnNumber(Tok.Tok.getLocation()) - 1,
             Tok.NewlinesBefore, "", "", Tok.Tok.getKind(),
             InPPDirective && !Tok.IsFirst));
}

void WhitespaceManager::replaceWhitespaceInToken(
    const FormatToken &Tok, unsigned Offset, unsigned ReplaceChars,
    StringRef PreviousPostfix, StringRef CurrentPrefix, bool InPPDirective,
    unsigned Newlines, unsigned Spaces) {
  Changes.push_back(Change(
      true, SourceRange(Tok.getStartOfNonWhitespace().getLocWithOffset(Offset),
                        Tok.getStartOfNonWhitespace().getLocWithOffset(
                            Offset + ReplaceChars)),
      Spaces, Spaces, Newlines, PreviousPostfix, CurrentPrefix,
      // If we don't add a newline this change doesn't start a comment. Thus,
      // when we align line comments, we don't need to treat this change as one.
      // FIXME: We still need to take this change in account to properly
      // calculate the new length of the comment and to calculate the changes
      // for which to do the alignment when aligning comments.
      Tok.Type == TT_LineComment && Newlines > 0 ? tok::comment : tok::unknown,
      InPPDirective && !Tok.IsFirst));
}

const tooling::Replacements &WhitespaceManager::generateReplacements() {
  if (Changes.empty())
    return Replaces;

  std::sort(Changes.begin(), Changes.end(), Change::IsBeforeInFile(SourceMgr));
  calculateLineBreakInformation();
  alignTrailingComments();
  alignEscapedNewlines();
  generateChanges();

  return Replaces;
}

void WhitespaceManager::calculateLineBreakInformation() {
  Changes[0].PreviousEndOfTokenColumn = 0;
  for (unsigned i = 1, e = Changes.size(); i != e; ++i) {
    unsigned OriginalWhitespaceStart =
        SourceMgr.getFileOffset(Changes[i].OriginalWhitespaceRange.getBegin());
    unsigned PreviousOriginalWhitespaceEnd = SourceMgr.getFileOffset(
        Changes[i - 1].OriginalWhitespaceRange.getEnd());
    Changes[i - 1].TokenLength = OriginalWhitespaceStart -
                                 PreviousOriginalWhitespaceEnd +
                                 Changes[i].PreviousLinePostfix.size() +
                                 Changes[i - 1].CurrentLinePrefix.size();

    Changes[i].PreviousEndOfTokenColumn =
        Changes[i - 1].StartOfTokenColumn + Changes[i - 1].TokenLength;

    Changes[i - 1].IsTrailingComment =
        (Changes[i].NewlinesBefore > 0 || Changes[i].Kind == tok::eof) &&
        Changes[i - 1].Kind == tok::comment;
  }
  // FIXME: The last token is currently not always an eof token; in those
  // cases, setting TokenLength of the last token to 0 is wrong.
  Changes.back().TokenLength = 0;
  Changes.back().IsTrailingComment = Changes.back().Kind == tok::comment;
}

void WhitespaceManager::alignTrailingComments() {
  unsigned MinColumn = 0;
  unsigned MaxColumn = UINT_MAX;
  unsigned StartOfSequence = 0;
  bool BreakBeforeNext = false;
  unsigned Newlines = 0;
  for (unsigned i = 0, e = Changes.size(); i != e; ++i) {
    unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
    // FIXME: Correctly handle ChangeMaxColumn in PP directives.
    unsigned ChangeMaxColumn = Style.ColumnLimit - Changes[i].TokenLength;
    Newlines += Changes[i].NewlinesBefore;
    if (Changes[i].IsTrailingComment) {
      // If this comment follows an } in column 0, it probably documents the
      // closing of a namespace and we don't want to align it.
      bool FollowsRBraceInColumn0 = i > 0 && Changes[i].NewlinesBefore == 0 &&
                                    Changes[i - 1].Kind == tok::r_brace &&
                                    Changes[i - 1].StartOfTokenColumn == 0;
      bool WasAlignedWithStartOfNextLine =
          // A comment on its own line.
          Changes[i].NewlinesBefore == 1 &&
          // Not the last line.
          i + 1 != e &&
          // The start of the next token was previously aligned with
          // the start of this comment.
          (SourceMgr.getSpellingColumnNumber(
               Changes[i].OriginalWhitespaceRange.getEnd()) ==
           SourceMgr.getSpellingColumnNumber(
               Changes[i + 1].OriginalWhitespaceRange.getEnd())) &&
          // Which is not a comment itself.
          Changes[i + 1].Kind != tok::comment;
      if (!Style.AlignTrailingComments || FollowsRBraceInColumn0) {
        alignTrailingComments(StartOfSequence, i, MinColumn);
        MinColumn = ChangeMinColumn;
        MaxColumn = ChangeMinColumn;
        StartOfSequence = i;
      } else if (BreakBeforeNext || Newlines > 1 ||
                 (ChangeMinColumn > MaxColumn || ChangeMaxColumn < MinColumn) ||
                 // Break the comment sequence if the previous line did not end
                 // in a trailing comment.
                 (Changes[i].NewlinesBefore == 1 && i > 0 &&
                  !Changes[i - 1].IsTrailingComment) ||
                 WasAlignedWithStartOfNextLine) {
        alignTrailingComments(StartOfSequence, i, MinColumn);
        MinColumn = ChangeMinColumn;
        MaxColumn = ChangeMaxColumn;
        StartOfSequence = i;
      } else {
        MinColumn = std::max(MinColumn, ChangeMinColumn);
        MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
      }
      BreakBeforeNext =
          (i == 0) || (Changes[i].NewlinesBefore > 1) ||
          // Never start a sequence with a comment at the beginning of
          // the line.
          (Changes[i].NewlinesBefore == 1 && StartOfSequence == i);
      Newlines = 0;
    }
  }
  alignTrailingComments(StartOfSequence, Changes.size(), MinColumn);
}

void WhitespaceManager::alignTrailingComments(unsigned Start, unsigned End,
                                              unsigned Column) {
  for (unsigned i = Start; i != End; ++i) {
    if (Changes[i].IsTrailingComment) {
      assert(Column >= Changes[i].StartOfTokenColumn);
      Changes[i].Spaces += Column - Changes[i].StartOfTokenColumn;
      Changes[i].StartOfTokenColumn = Column;
    }
  }
}

void WhitespaceManager::alignEscapedNewlines() {
  unsigned MaxEndOfLine = 0;
  unsigned StartOfMacro = 0;
  for (unsigned i = 1, e = Changes.size(); i < e; ++i) {
    Change &C = Changes[i];
    if (C.NewlinesBefore > 0) {
      if (C.ContinuesPPDirective) {
        if (Style.AlignEscapedNewlinesLeft)
          MaxEndOfLine = std::max(C.PreviousEndOfTokenColumn + 2, MaxEndOfLine);
        else
          MaxEndOfLine = Style.ColumnLimit;
      } else {
        alignEscapedNewlines(StartOfMacro + 1, i, MaxEndOfLine);
        MaxEndOfLine = 0;
        StartOfMacro = i;
      }
    }
  }
  alignEscapedNewlines(StartOfMacro + 1, Changes.size(), MaxEndOfLine);
}

void WhitespaceManager::alignEscapedNewlines(unsigned Start, unsigned End,
                                             unsigned Column) {
  for (unsigned i = Start; i < End; ++i) {
    Change &C = Changes[i];
    if (C.NewlinesBefore > 0) {
      assert(C.ContinuesPPDirective);
      if (C.PreviousEndOfTokenColumn + 1 > Column)
        C.EscapedNewlineColumn = 0;
      else
        C.EscapedNewlineColumn = Column;
    }
  }
}

void WhitespaceManager::generateChanges() {
  for (unsigned i = 0, e = Changes.size(); i != e; ++i) {
    const Change &C = Changes[i];
    if (C.CreateReplacement) {
      std::string ReplacementText =
          C.PreviousLinePostfix +
          (C.ContinuesPPDirective
               ? getNewlineText(C.NewlinesBefore, C.Spaces,
                                C.PreviousEndOfTokenColumn,
                                C.EscapedNewlineColumn)
               : getNewlineText(C.NewlinesBefore, C.Spaces)) +
          C.CurrentLinePrefix;
      storeReplacement(C.OriginalWhitespaceRange, ReplacementText);
    }
  }
}

void WhitespaceManager::storeReplacement(const SourceRange &Range,
                                         StringRef Text) {
  unsigned WhitespaceLength = SourceMgr.getFileOffset(Range.getEnd()) -
                              SourceMgr.getFileOffset(Range.getBegin());
  // Don't create a replacement, if it does not change anything.
  if (StringRef(SourceMgr.getCharacterData(Range.getBegin()),
                WhitespaceLength) == Text)
    return;
  Replaces.insert(tooling::Replacement(
      SourceMgr, CharSourceRange::getCharRange(Range), Text));
}

std::string WhitespaceManager::getNewlineText(unsigned Newlines,
                                              unsigned Spaces) {
  return std::string(Newlines, '\n') + getIndentText(Spaces);
}

std::string WhitespaceManager::getNewlineText(unsigned Newlines,
                                              unsigned Spaces,
                                              unsigned PreviousEndOfTokenColumn,
                                              unsigned EscapedNewlineColumn) {
  std::string NewlineText;
  if (Newlines > 0) {
    unsigned Offset =
        std::min<int>(EscapedNewlineColumn - 1, PreviousEndOfTokenColumn);
    for (unsigned i = 0; i < Newlines; ++i) {
      NewlineText += std::string(EscapedNewlineColumn - Offset - 1, ' ');
      NewlineText += "\\\n";
      Offset = 0;
    }
  }
  return NewlineText + getIndentText(Spaces);
}

std::string WhitespaceManager::getIndentText(unsigned Spaces) {
  if (!Style.UseTab)
    return std::string(Spaces, ' ');

  return std::string(Spaces / Style.IndentWidth, '\t') +
         std::string(Spaces % Style.IndentWidth, ' ');
}

} // namespace format
} // namespace clang
