//===--- TokenAnnotator.h - Format C++ code ---------------------*- 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 a token annotator, i.e. creates
/// \c AnnotatedTokens out of \c FormatTokens with required extra information.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_LIB_FORMAT_TOKENANNOTATOR_H
#define LLVM_CLANG_LIB_FORMAT_TOKENANNOTATOR_H

#include "UnwrappedLineParser.h"

namespace clang {
namespace format {

enum LineType {
  LT_Invalid,
  LT_ImportStatement,
  LT_ObjCDecl, // An @interface, @implementation, or @protocol line.
  LT_ObjCMethodDecl,
  LT_ObjCProperty, // An @property line.
  LT_Other,
  LT_PreprocessorDirective,
  LT_VirtualFunctionDecl,
  LT_ArrayOfStructInitializer,
  LT_CommentAbovePPDirective,
};

enum ScopeType {
  // Contained in class declaration/definition.
  ST_Class,
  // Contained within function definition.
  ST_Function,
  // Contained within other scope block (loop, if/else, etc).
  ST_Other,
};

class AnnotatedLine {
public:
  AnnotatedLine(const UnwrappedLine &Line)
      : First(Line.Tokens.front().Tok), Level(Line.Level),
        PPLevel(Line.PPLevel),
        MatchingOpeningBlockLineIndex(Line.MatchingOpeningBlockLineIndex),
        MatchingClosingBlockLineIndex(Line.MatchingClosingBlockLineIndex),
        InPPDirective(Line.InPPDirective),
        InPragmaDirective(Line.InPragmaDirective),
        InMacroBody(Line.InMacroBody),
        MustBeDeclaration(Line.MustBeDeclaration), MightBeFunctionDecl(false),
        IsMultiVariableDeclStmt(false), Affected(false),
        LeadingEmptyLinesAffected(false), ChildrenAffected(false),
        ReturnTypeWrapped(false), IsContinuation(Line.IsContinuation),
        FirstStartColumn(Line.FirstStartColumn) {
    assert(!Line.Tokens.empty());

    // Calculate Next and Previous for all tokens. Note that we must overwrite
    // Next and Previous for every token, as previous formatting runs might have
    // left them in a different state.
    First->Previous = nullptr;
    FormatToken *Current = First;
    addChildren(Line.Tokens.front(), Current);
    for (const UnwrappedLineNode &Node : llvm::drop_begin(Line.Tokens)) {
      if (Node.Tok->MacroParent)
        ContainsMacroCall = true;
      Current->Next = Node.Tok;
      Node.Tok->Previous = Current;
      Current = Current->Next;
      addChildren(Node, Current);
      // FIXME: if we add children, previous will point to the token before
      // the children; changing this requires significant changes across
      // clang-format.
    }
    Last = Current;
    Last->Next = nullptr;
  }

  void addChildren(const UnwrappedLineNode &Node, FormatToken *Current) {
    Current->Children.clear();
    for (const auto &Child : Node.Children) {
      Children.push_back(new AnnotatedLine(Child));
      if (Children.back()->ContainsMacroCall)
        ContainsMacroCall = true;
      Current->Children.push_back(Children.back());
    }
  }

  size_t size() const {
    size_t Size = 1;
    for (const auto *Child : Children)
      Size += Child->size();
    return Size;
  }

  ~AnnotatedLine() {
    for (AnnotatedLine *Child : Children)
      delete Child;
    FormatToken *Current = First;
    while (Current) {
      Current->Children.clear();
      Current->Role.reset();
      Current = Current->Next;
    }
  }

  bool isComment() const {
    return First && First->is(tok::comment) && !First->getNextNonComment();
  }

  /// \c true if this line starts with the given tokens in order, ignoring
  /// comments.
  template <typename... Ts> bool startsWith(Ts... Tokens) const {
    return First && First->startsSequence(Tokens...);
  }

  /// \c true if this line ends with the given tokens in reversed order,
  /// ignoring comments.
  /// For example, given tokens [T1, T2, T3, ...], the function returns true if
  /// this line is like "... T3 T2 T1".
  template <typename... Ts> bool endsWith(Ts... Tokens) const {
    return Last && Last->endsSequence(Tokens...);
  }

  /// \c true if this line looks like a function definition instead of a
  /// function declaration. Asserts MightBeFunctionDecl.
  bool mightBeFunctionDefinition() const {
    assert(MightBeFunctionDecl);
    // Try to determine if the end of a stream of tokens is either the
    // Definition or the Declaration for a function. It does this by looking for
    // the ';' in foo(); and using that it ends with a ; to know this is the
    // Definition, however the line could end with
    //    foo(); /* comment */
    // or
    //    foo(); // comment
    // or
    //    foo() // comment
    // endsWith() ignores the comment.
    return !endsWith(tok::semi);
  }

  /// \c true if this line starts a namespace definition.
  bool startsWithNamespace() const {
    return startsWith(tok::kw_namespace) || startsWith(TT_NamespaceMacro) ||
           startsWith(tok::kw_inline, tok::kw_namespace) ||
           startsWith(tok::kw_export, tok::kw_namespace);
  }

  FormatToken *getFirstNonComment() const {
    assert(First);
    return First->is(tok::comment) ? First->getNextNonComment() : First;
  }

  FormatToken *getLastNonComment() const {
    assert(Last);
    return Last->is(tok::comment) ? Last->getPreviousNonComment() : Last;
  }

  FormatToken *First;
  FormatToken *Last;

  SmallVector<AnnotatedLine *, 0> Children;

  LineType Type;
  unsigned Level;
  unsigned PPLevel;
  size_t MatchingOpeningBlockLineIndex;
  size_t MatchingClosingBlockLineIndex;
  bool InPPDirective;
  bool InPragmaDirective;
  bool InMacroBody;
  bool MustBeDeclaration;
  bool MightBeFunctionDecl;
  bool IsMultiVariableDeclStmt;

  /// \c True if this line contains a macro call for which an expansion exists.
  bool ContainsMacroCall = false;

  /// \c True if this line should be formatted, i.e. intersects directly or
  /// indirectly with one of the input ranges.
  bool Affected;

  /// \c True if the leading empty lines of this line intersect with one of the
  /// input ranges.
  bool LeadingEmptyLinesAffected;

  /// \c True if one of this line's children intersects with an input range.
  bool ChildrenAffected;

  /// \c True if breaking after last attribute group in function return type.
  bool ReturnTypeWrapped;

  /// \c True if this line should be indented by ContinuationIndent in addition
  /// to the normal indention level.
  bool IsContinuation;

  unsigned FirstStartColumn;

private:
  // Disallow copying.
  AnnotatedLine(const AnnotatedLine &) = delete;
  void operator=(const AnnotatedLine &) = delete;
};

/// Determines extra information about the tokens comprising an
/// \c UnwrappedLine.
class TokenAnnotator {
public:
  TokenAnnotator(const FormatStyle &Style, const AdditionalKeywords &Keywords)
      : Style(Style), IsCpp(Style.isCpp()), Keywords(Keywords) {}

  /// Adapts the indent levels of comment lines to the indent of the
  /// subsequent line.
  // FIXME: Can/should this be done in the UnwrappedLineParser?
  void setCommentLineLevels(SmallVectorImpl<AnnotatedLine *> &Lines) const;

  void annotate(AnnotatedLine &Line);
  void calculateFormattingInformation(AnnotatedLine &Line) const;

private:
  /// Calculate the penalty for splitting before \c Tok.
  unsigned splitPenalty(const AnnotatedLine &Line, const FormatToken &Tok,
                        bool InFunctionDecl) const;

  bool spaceRequiredBeforeParens(const FormatToken &Right) const;

  bool spaceRequiredBetween(const AnnotatedLine &Line, const FormatToken &Left,
                            const FormatToken &Right) const;

  bool spaceRequiredBefore(const AnnotatedLine &Line,
                           const FormatToken &Right) const;

  bool mustBreakBefore(const AnnotatedLine &Line,
                       const FormatToken &Right) const;

  bool canBreakBefore(const AnnotatedLine &Line,
                      const FormatToken &Right) const;

  bool mustBreakForReturnType(const AnnotatedLine &Line) const;

  void printDebugInfo(const AnnotatedLine &Line) const;

  void calculateUnbreakableTailLengths(AnnotatedLine &Line) const;

  void calculateArrayInitializerColumnList(AnnotatedLine &Line) const;

  FormatToken *calculateInitializerColumnList(AnnotatedLine &Line,
                                              FormatToken *CurrentToken,
                                              unsigned Depth) const;
  FormatStyle::PointerAlignmentStyle
  getTokenReferenceAlignment(const FormatToken &PointerOrReference) const;

  FormatStyle::PointerAlignmentStyle getTokenPointerOrReferenceAlignment(
      const FormatToken &PointerOrReference) const;

  const FormatStyle &Style;

  bool IsCpp;

  const AdditionalKeywords &Keywords;

  SmallVector<ScopeType> Scopes;
};

} // end namespace format
} // end namespace clang

#endif
