//===--- 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
