//===--- DefinitionBlockSeparator.cpp ---------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file implements DefinitionBlockSeparator, a TokenAnalyzer that inserts
/// or removes empty lines separating definition blocks like classes, structs,
/// functions, enums, and namespaces in between.
///
//===----------------------------------------------------------------------===//

#include "DefinitionBlockSeparator.h"
#include "llvm/Support/Debug.h"
#define DEBUG_TYPE "definition-block-separator"

namespace clang {
namespace format {
std::pair<tooling::Replacements, unsigned> DefinitionBlockSeparator::analyze(
    TokenAnnotator &Annotator, SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
    FormatTokenLexer &Tokens) {
  assert(Style.SeparateDefinitionBlocks != FormatStyle::SDS_Leave);
  AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
  tooling::Replacements Result;
  separateBlocks(AnnotatedLines, Result, Tokens);
  return {Result, 0};
}

void DefinitionBlockSeparator::separateBlocks(
    SmallVectorImpl<AnnotatedLine *> &Lines, tooling::Replacements &Result,
    FormatTokenLexer &Tokens) {
  const bool IsNeverStyle =
      Style.SeparateDefinitionBlocks == FormatStyle::SDS_Never;
  const AdditionalKeywords &ExtraKeywords = Tokens.getKeywords();
  auto GetBracketLevelChange = [](const FormatToken *Tok) {
    if (Tok->isOneOf(tok::l_brace, tok::l_paren, tok::l_square))
      return 1;
    if (Tok->isOneOf(tok::r_brace, tok::r_paren, tok::r_square))
      return -1;
    return 0;
  };
  auto LikelyDefinition = [&](const AnnotatedLine *Line,
                              bool ExcludeEnum = false) {
    if ((Line->MightBeFunctionDecl && Line->mightBeFunctionDefinition()) ||
        Line->startsWithNamespace()) {
      return true;
    }
    int BracketLevel = 0;
    for (const FormatToken *CurrentToken = Line->First; CurrentToken;
         CurrentToken = CurrentToken->Next) {
      if (BracketLevel == 0) {
        if ((CurrentToken->isOneOf(tok::kw_class, tok::kw_struct,
                                   tok::kw_union) ||
             (Style.isJavaScript() &&
              CurrentToken->is(ExtraKeywords.kw_function)))) {
          return true;
        }
        if (!ExcludeEnum && CurrentToken->is(tok::kw_enum))
          return true;
      }
      BracketLevel += GetBracketLevelChange(CurrentToken);
    }
    return false;
  };
  unsigned NewlineCount =
      (Style.SeparateDefinitionBlocks == FormatStyle::SDS_Always ? 1 : 0) + 1;
  WhitespaceManager Whitespaces(
      Env.getSourceManager(), Style,
      Style.LineEnding > FormatStyle::LE_CRLF
          ? WhitespaceManager::inputUsesCRLF(
                Env.getSourceManager().getBufferData(Env.getFileID()),
                Style.LineEnding == FormatStyle::LE_DeriveCRLF)
          : Style.LineEnding == FormatStyle::LE_CRLF);
  for (unsigned I = 0; I < Lines.size(); ++I) {
    const auto &CurrentLine = Lines[I];
    if (CurrentLine->InPPDirective)
      continue;
    FormatToken *TargetToken = nullptr;
    AnnotatedLine *TargetLine;
    auto OpeningLineIndex = CurrentLine->MatchingOpeningBlockLineIndex;
    AnnotatedLine *OpeningLine = nullptr;
    const auto IsAccessSpecifierToken = [](const FormatToken *Token) {
      return Token->isAccessSpecifier() || Token->isObjCAccessSpecifier();
    };
    const auto InsertReplacement = [&](const int NewlineToInsert) {
      assert(TargetLine);
      assert(TargetToken);

      // Do not handle EOF newlines.
      if (TargetToken->is(tok::eof))
        return;
      if (IsAccessSpecifierToken(TargetToken) ||
          (OpeningLineIndex > 0 &&
           IsAccessSpecifierToken(Lines[OpeningLineIndex - 1]->First))) {
        return;
      }
      if (!TargetLine->Affected)
        return;
      Whitespaces.replaceWhitespace(*TargetToken, NewlineToInsert,
                                    TargetToken->OriginalColumn,
                                    TargetToken->OriginalColumn);
    };
    const auto IsPPConditional = [&](const size_t LineIndex) {
      const auto &Line = Lines[LineIndex];
      return Line->First->is(tok::hash) && Line->First->Next &&
             Line->First->Next->isOneOf(tok::pp_if, tok::pp_ifdef, tok::pp_else,
                                        tok::pp_ifndef, tok::pp_elifndef,
                                        tok::pp_elifdef, tok::pp_elif,
                                        tok::pp_endif);
    };
    const auto FollowingOtherOpening = [&]() {
      return OpeningLineIndex == 0 ||
             Lines[OpeningLineIndex - 1]->Last->opensScope() ||
             IsPPConditional(OpeningLineIndex - 1);
    };
    const auto HasEnumOnLine = [&]() {
      bool FoundEnumKeyword = false;
      int BracketLevel = 0;
      for (const FormatToken *CurrentToken = CurrentLine->First; CurrentToken;
           CurrentToken = CurrentToken->Next) {
        if (BracketLevel == 0) {
          if (CurrentToken->is(tok::kw_enum))
            FoundEnumKeyword = true;
          else if (FoundEnumKeyword && CurrentToken->is(tok::l_brace))
            return true;
        }
        BracketLevel += GetBracketLevelChange(CurrentToken);
      }
      return FoundEnumKeyword && I + 1 < Lines.size() &&
             Lines[I + 1]->First->is(tok::l_brace);
    };

    bool IsDefBlock = false;
    const auto MayPrecedeDefinition = [&](const int Direction = -1) {
      assert(Direction >= -1);
      assert(Direction <= 1);
      const size_t OperateIndex = OpeningLineIndex + Direction;
      assert(OperateIndex < Lines.size());
      const auto &OperateLine = Lines[OperateIndex];
      if (LikelyDefinition(OperateLine))
        return false;

      if (OperateLine->First->is(tok::comment))
        return true;

      // A single line identifier that is not in the last line.
      if (OperateLine->First->is(tok::identifier) &&
          OperateLine->First == OperateLine->Last &&
          OperateIndex + 1 < Lines.size()) {
        // UnwrappedLineParser's recognition of free-standing macro like
        // Q_OBJECT may also recognize some uppercased type names that may be
        // used as return type as that kind of macros, which is a bit hard to
        // distinguish one from another purely from token patterns. Here, we
        // try not to add new lines below those identifiers.
        AnnotatedLine *NextLine = Lines[OperateIndex + 1];
        if (NextLine->MightBeFunctionDecl &&
            NextLine->mightBeFunctionDefinition() &&
            NextLine->First->NewlinesBefore == 1 &&
            OperateLine->First->is(TT_FunctionLikeOrFreestandingMacro)) {
          return true;
        }
      }

      if ((Style.isCSharp() && OperateLine->First->is(TT_AttributeSquare)))
        return true;
      return false;
    };

    if (HasEnumOnLine() &&
        !LikelyDefinition(CurrentLine, /*ExcludeEnum=*/true)) {
      // We have no scope opening/closing information for enum.
      IsDefBlock = true;
      OpeningLineIndex = I;
      while (OpeningLineIndex > 0 && MayPrecedeDefinition())
        --OpeningLineIndex;
      OpeningLine = Lines[OpeningLineIndex];
      TargetLine = OpeningLine;
      TargetToken = TargetLine->First;
      if (!FollowingOtherOpening())
        InsertReplacement(NewlineCount);
      else if (IsNeverStyle)
        InsertReplacement(OpeningLineIndex != 0);
      TargetLine = CurrentLine;
      TargetToken = TargetLine->First;
      while (TargetToken && !TargetToken->is(tok::r_brace))
        TargetToken = TargetToken->Next;
      if (!TargetToken)
        while (I < Lines.size() && !Lines[I]->First->is(tok::r_brace))
          ++I;
    } else if (CurrentLine->First->closesScope()) {
      if (OpeningLineIndex > Lines.size())
        continue;
      // Handling the case that opening brace has its own line, with checking
      // whether the last line already had an opening brace to guard against
      // misrecognition.
      if (OpeningLineIndex > 0 &&
          Lines[OpeningLineIndex]->First->is(tok::l_brace) &&
          Lines[OpeningLineIndex - 1]->Last->isNot(tok::l_brace)) {
        --OpeningLineIndex;
      }
      OpeningLine = Lines[OpeningLineIndex];
      // Closing a function definition.
      if (LikelyDefinition(OpeningLine)) {
        IsDefBlock = true;
        while (OpeningLineIndex > 0 && MayPrecedeDefinition())
          --OpeningLineIndex;
        OpeningLine = Lines[OpeningLineIndex];
        TargetLine = OpeningLine;
        TargetToken = TargetLine->First;
        if (!FollowingOtherOpening()) {
          // Avoid duplicated replacement.
          if (TargetToken->isNot(tok::l_brace))
            InsertReplacement(NewlineCount);
        } else if (IsNeverStyle) {
          InsertReplacement(OpeningLineIndex != 0);
        }
      }
    }

    // Not the last token.
    if (IsDefBlock && I + 1 < Lines.size()) {
      OpeningLineIndex = I + 1;
      TargetLine = Lines[OpeningLineIndex];
      TargetToken = TargetLine->First;

      // No empty line for continuously closing scopes. The token will be
      // handled in another case if the line following is opening a
      // definition.
      if (!TargetToken->closesScope() && !IsPPConditional(OpeningLineIndex)) {
        // Check whether current line may precede a definition line.
        while (OpeningLineIndex + 1 < Lines.size() &&
               MayPrecedeDefinition(/*Direction=*/0)) {
          ++OpeningLineIndex;
        }
        TargetLine = Lines[OpeningLineIndex];
        if (!LikelyDefinition(TargetLine)) {
          OpeningLineIndex = I + 1;
          TargetLine = Lines[I + 1];
          TargetToken = TargetLine->First;
          InsertReplacement(NewlineCount);
        }
      } else if (IsNeverStyle) {
        InsertReplacement(/*NewlineToInsert=*/1);
      }
    }
  }
  for (const auto &R : Whitespaces.generateReplacements()) {
    // The add method returns an Error instance which simulates program exit
    // code through overloading boolean operator, thus false here indicates
    // success.
    if (Result.add(R))
      return;
  }
}
} // namespace format
} // namespace clang
