132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper//===--- TokenAnnotator.h - Format C++ code ---------------------*- C++ -*-===//
232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper//
332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper//                     The LLVM Compiler Infrastructure
432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper//
532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper// This file is distributed under the University of Illinois Open Source
632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper// License. See LICENSE.TXT for details.
732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper//
832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper//===----------------------------------------------------------------------===//
932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper///
1032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper/// \file
1132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper/// \brief This file implements a token annotator, i.e. creates
1232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper/// \c AnnotatedTokens out of \c FormatTokens with required extra information.
1332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper///
1432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper//===----------------------------------------------------------------------===//
1532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
1632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper#ifndef LLVM_CLANG_FORMAT_TOKEN_ANNOTATOR_H
1732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper#define LLVM_CLANG_FORMAT_TOKEN_ANNOTATOR_H
1832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
1932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper#include "UnwrappedLineParser.h"
2032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper#include "clang/Format/Format.h"
2132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper#include <string>
2232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
2332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jaspernamespace clang {
2432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasperclass SourceManager;
2532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
2632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jaspernamespace format {
2732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
2832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasperenum LineType {
2932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  LT_Invalid,
3032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  LT_Other,
3132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  LT_PreprocessorDirective,
3232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  LT_VirtualFunctionDecl,
3332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  LT_ObjCDecl, // An @interface, @implementation, or @protocol line.
3432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  LT_ObjCMethodDecl,
3532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  LT_ObjCProperty // An @property line.
3632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper};
3732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
3832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasperclass AnnotatedLine {
3932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasperpublic:
4032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  AnnotatedLine(const UnwrappedLine &Line)
41567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper      : First(Line.Tokens.front().Tok), Level(Line.Level),
4232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        InPPDirective(Line.InPPDirective),
4353e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper        MustBeDeclaration(Line.MustBeDeclaration), MightBeFunctionDecl(false),
44ef8225444452a1486bd721f3285301fe84643b00Stephen Hines        Affected(false), LeadingEmptyLinesAffected(false),
45ef8225444452a1486bd721f3285301fe84643b00Stephen Hines        ChildrenAffected(false) {
4632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    assert(!Line.Tokens.empty());
47d186f0b4c15d4c63e0ae7fbe6ca3207871ba2eb9Manuel Klimek
48d186f0b4c15d4c63e0ae7fbe6ca3207871ba2eb9Manuel Klimek    // Calculate Next and Previous for all tokens. Note that we must overwrite
49d186f0b4c15d4c63e0ae7fbe6ca3207871ba2eb9Manuel Klimek    // Next and Previous for every token, as previous formatting runs might have
50d186f0b4c15d4c63e0ae7fbe6ca3207871ba2eb9Manuel Klimek    // left them in a different state.
516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    First->Previous = nullptr;
52b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek    FormatToken *Current = First;
53567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper    for (std::list<UnwrappedLineNode>::const_iterator I = ++Line.Tokens.begin(),
54567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper                                                      E = Line.Tokens.end();
5532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper         I != E; ++I) {
56567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper      const UnwrappedLineNode &Node = *I;
57567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper      Current->Next = I->Tok;
58567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper      I->Tok->Previous = Current;
59b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek      Current = Current->Next;
60852bce4ba3c59669a80d4755f07782a3c28c606bDaniel Jasper      Current->Children.clear();
61567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper      for (SmallVectorImpl<UnwrappedLine>::const_iterator
62567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper               I = Node.Children.begin(),
63567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper               E = Node.Children.end();
64567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper           I != E; ++I) {
65567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper        Children.push_back(new AnnotatedLine(*I));
66567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper        Current->Children.push_back(Children.back());
67567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper      }
6832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    }
6932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    Last = Current;
706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    Last->Next = nullptr;
7132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  }
7232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
73567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper  ~AnnotatedLine() {
74567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper    for (unsigned i = 0, e = Children.size(); i != e; ++i) {
75567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper      delete Children[i];
76567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper    }
77567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper  }
78567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper
79b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  FormatToken *First;
80b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  FormatToken *Last;
8132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
82b77d741691a2775b5c31e29f021203cc659c26dfDaniel Jasper  SmallVector<AnnotatedLine *, 0> Children;
83567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper
8432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  LineType Type;
8532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  unsigned Level;
8632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  bool InPPDirective;
8732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  bool MustBeDeclaration;
883c08a818a6ac9115fe8880af9bbf5a0a87bdffaaDaniel Jasper  bool MightBeFunctionDecl;
89567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper
90651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// \c True if this line should be formatted, i.e. intersects directly or
91651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// indirectly with one of the input ranges.
92651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool Affected;
93651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
94651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// \c True if the leading empty lines of this line intersect with one of the
95651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// input ranges.
96651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool LeadingEmptyLinesAffected;
97651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
98651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// \c True if a one of this line's children intersects with an input range.
99651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool ChildrenAffected;
100651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
101567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasperprivate:
102567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper  // Disallow copying.
103567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper  AnnotatedLine(const AnnotatedLine &) LLVM_DELETED_FUNCTION;
104567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper  void operator=(const AnnotatedLine &) LLVM_DELETED_FUNCTION;
10532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper};
10632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
10732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper/// \brief Determines extra information about the tokens comprising an
10832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper/// \c UnwrappedLine.
10932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasperclass TokenAnnotator {
11032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasperpublic:
11100895106f9ed602af67984ec4d225a0cdc8c12afAlexander Kornienko  TokenAnnotator(const FormatStyle &Style, IdentifierInfo &Ident_in)
11200895106f9ed602af67984ec4d225a0cdc8c12afAlexander Kornienko      : Style(Style), Ident_in(Ident_in) {}
11332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
114b77d741691a2775b5c31e29f021203cc659c26dfDaniel Jasper  /// \brief Adapts the indent levels of comment lines to the indent of the
115b77d741691a2775b5c31e29f021203cc659c26dfDaniel Jasper  /// subsequent line.
116b77d741691a2775b5c31e29f021203cc659c26dfDaniel Jasper  // FIXME: Can/should this be done in the UnwrappedLineParser?
117b77d741691a2775b5c31e29f021203cc659c26dfDaniel Jasper  void setCommentLineLevels(SmallVectorImpl<AnnotatedLine *> &Lines);
118b77d741691a2775b5c31e29f021203cc659c26dfDaniel Jasper
1198ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper  void annotate(AnnotatedLine &Line);
1208ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper  void calculateFormattingInformation(AnnotatedLine &Line);
12132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
12232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasperprivate:
12332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  /// \brief Calculate the penalty for splitting before \c Tok.
124dbfb5f37f4d003ae6935b87a103b7827d5069690Daniel Jasper  unsigned splitPenalty(const AnnotatedLine &Line, const FormatToken &Tok,
125dbfb5f37f4d003ae6935b87a103b7827d5069690Daniel Jasper                        bool InFunctionDecl);
12632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
127b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  bool spaceRequiredBetween(const AnnotatedLine &Line, const FormatToken &Left,
128b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek                            const FormatToken &Right);
12932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
130b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  bool spaceRequiredBefore(const AnnotatedLine &Line, const FormatToken &Tok);
13132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
132ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper  bool mustBreakBefore(const AnnotatedLine &Line, const FormatToken &Right);
133ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper
134b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek  bool canBreakBefore(const AnnotatedLine &Line, const FormatToken &Right);
13532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
136bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper  void printDebugInfo(const AnnotatedLine &Line);
137bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper
138e573c3f7fc40e813559ab4ff1e7eec4f66f1a50fManuel Klimek  void calculateUnbreakableTailLengths(AnnotatedLine &Line);
139e573c3f7fc40e813559ab4ff1e7eec4f66f1a50fManuel Klimek
1408ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper  const FormatStyle &Style;
141c2e6d2a4a7fe9dfa7d52a38c6048b7b18e6b591aNico Weber
142c2e6d2a4a7fe9dfa7d52a38c6048b7b18e6b591aNico Weber  // Contextual keywords:
143c2e6d2a4a7fe9dfa7d52a38c6048b7b18e6b591aNico Weber  IdentifierInfo &Ident_in;
14432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper};
14532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
14632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} // end namespace format
14732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} // end namespace clang
14832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
14932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper#endif // LLVM_CLANG_FORMAT_TOKEN_ANNOTATOR_H
150