]> granicus.if.org Git - clang/blobdiff - lib/Format/TokenAnnotator.h
Header guard canonicalization, clang part.
[clang] / lib / Format / TokenAnnotator.h
index 506f271dc5d15de106cf4062710c536243bae03c..88adc7503d327e3303d08b6c983b5e88d6a0b2a1 100644 (file)
 ///
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_CLANG_FORMAT_TOKEN_ANNOTATOR_H
-#define LLVM_CLANG_FORMAT_TOKEN_ANNOTATOR_H
+#ifndef LLVM_CLANG_LIB_FORMAT_TOKENANNOTATOR_H
+#define LLVM_CLANG_LIB_FORMAT_TOKENANNOTATOR_H
 
 #include "UnwrappedLineParser.h"
-#include "clang/Basic/OperatorPrecedence.h"
 #include "clang/Format/Format.h"
 #include <string>
 
 namespace clang {
-class Lexer;
 class SourceManager;
 
 namespace format {
 
-enum TokenType {
-  TT_BinaryOperator,
-  TT_BlockComment,
-  TT_CastRParen,
-  TT_ConditionalExpr,
-  TT_CtorInitializerColon,
-  TT_ImplicitStringLiteral,
-  TT_LineComment,
-  TT_ObjCArrayLiteral,
-  TT_ObjCBlockLParen,
-  TT_ObjCDecl,
-  TT_ObjCForIn,
-  TT_ObjCMethodExpr,
-  TT_ObjCMethodSpecifier,
-  TT_ObjCProperty,
-  TT_ObjCSelectorName,
-  TT_OverloadedOperatorLParen,
-  TT_PointerOrReference,
-  TT_PureVirtualSpecifier,
-  TT_RangeBasedForLoopColon,
-  TT_StartOfName,
-  TT_TemplateCloser,
-  TT_TemplateOpener,
-  TT_TrailingUnaryOperator,
-  TT_UnaryOperator,
-  TT_Unknown
-};
-
 enum LineType {
   LT_Invalid,
   LT_Other,
-  LT_BuilderTypeCall,
   LT_PreprocessorDirective,
   LT_VirtualFunctionDecl,
   LT_ObjCDecl, // An @interface, @implementation, or @protocol line.
@@ -66,143 +35,109 @@ enum LineType {
   LT_ObjCProperty // An @property line.
 };
 
-class AnnotatedToken {
-public:
-  explicit AnnotatedToken(const FormatToken &FormatTok)
-      : FormatTok(FormatTok), Type(TT_Unknown), SpacesRequiredBefore(0),
-        CanBreakBefore(false), MustBreakBefore(false),
-        ClosesTemplateDeclaration(false), MatchingParen(NULL),
-        ParameterCount(1), BindingStrength(0), SplitPenalty(0),
-        LongestObjCSelectorName(0), Parent(NULL), FakeLParens(0),
-        FakeRParens(0) {
-  }
-
-  bool is(tok::TokenKind Kind) const { return FormatTok.Tok.is(Kind); }
-  bool isNot(tok::TokenKind Kind) const { return FormatTok.Tok.isNot(Kind); }
-
-  bool isObjCAtKeyword(tok::ObjCKeywordKind Kind) const {
-    return FormatTok.Tok.isObjCAtKeyword(Kind);
-  }
-
-  FormatToken FormatTok;
-
-  TokenType Type;
-
-  unsigned SpacesRequiredBefore;
-  bool CanBreakBefore;
-  bool MustBreakBefore;
-
-  bool ClosesTemplateDeclaration;
-
-  AnnotatedToken *MatchingParen;
-
-  /// \brief Number of parameters, if this is "(", "[" or "<".
-  ///
-  /// This is initialized to 1 as we don't need to distinguish functions with
-  /// 0 parameters from functions with 1 parameter. Thus, we can simply count
-  /// the number of commas.
-  unsigned ParameterCount;
-
-  /// \brief The total length of the line up to and including this token.
-  unsigned TotalLength;
-
-  // FIXME: Come up with a 'cleaner' concept.
-  /// \brief The binding strength of a token. This is a combined value of
-  /// operator precedence, parenthesis nesting, etc.
-  unsigned BindingStrength;
-
-  /// \brief Penalty for inserting a line break before this token.
-  unsigned SplitPenalty;
-
-  /// \brief If this is the first ObjC selector name in an ObjC method
-  /// definition or call, this contains the length of the longest name.
-  unsigned LongestObjCSelectorName;
-
-  std::vector<AnnotatedToken> Children;
-  AnnotatedToken *Parent;
-
-  /// \brief Insert this many fake ( before this token for correct indentation.
-  unsigned FakeLParens;
-  /// \brief Insert this many fake ) after this token for correct indentation.
-  unsigned FakeRParens;
-
-  const AnnotatedToken *getPreviousNoneComment() const {
-    AnnotatedToken *Tok = Parent;
-    while (Tok != NULL && Tok->is(tok::comment))
-      Tok = Tok->Parent;
-    return Tok;
-  }
-};
-
 class AnnotatedLine {
 public:
   AnnotatedLine(const UnwrappedLine &Line)
-      : First(Line.Tokens.front()), Level(Line.Level),
+      : First(Line.Tokens.front().Tok), Level(Line.Level),
         InPPDirective(Line.InPPDirective),
-        MustBeDeclaration(Line.MustBeDeclaration) {
+        MustBeDeclaration(Line.MustBeDeclaration), MightBeFunctionDecl(false),
+        Affected(false), LeadingEmptyLinesAffected(false),
+        ChildrenAffected(false) {
     assert(!Line.Tokens.empty());
-    AnnotatedToken *Current = &First;
-    for (std::list<FormatToken>::const_iterator I = ++Line.Tokens.begin(),
-                                                E = Line.Tokens.end();
+
+    // 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;
+    for (std::list<UnwrappedLineNode>::const_iterator I = ++Line.Tokens.begin(),
+                                                      E = Line.Tokens.end();
          I != E; ++I) {
-      Current->Children.push_back(AnnotatedToken(*I));
-      Current->Children[0].Parent = Current;
-      Current = &Current->Children[0];
+      const UnwrappedLineNode &Node = *I;
+      Current->Next = I->Tok;
+      I->Tok->Previous = Current;
+      Current = Current->Next;
+      Current->Children.clear();
+      for (SmallVectorImpl<UnwrappedLine>::const_iterator
+               I = Node.Children.begin(),
+               E = Node.Children.end();
+           I != E; ++I) {
+        Children.push_back(new AnnotatedLine(*I));
+        Current->Children.push_back(Children.back());
+      }
     }
     Last = Current;
+    Last->Next = nullptr;
   }
-  AnnotatedLine(const AnnotatedLine &Other)
-      : First(Other.First), Type(Other.Type), Level(Other.Level),
-        InPPDirective(Other.InPPDirective),
-        MustBeDeclaration(Other.MustBeDeclaration) {
-    Last = &First;
-    while (!Last->Children.empty()) {
-      Last->Children[0].Parent = Last;
-      Last = &Last->Children[0];
+
+  ~AnnotatedLine() {
+    for (unsigned i = 0, e = Children.size(); i != e; ++i) {
+      delete Children[i];
     }
   }
 
-  AnnotatedToken First;
-  AnnotatedToken *Last;
+  FormatToken *First;
+  FormatToken *Last;
+
+  SmallVector<AnnotatedLine *, 0> Children;
 
   LineType Type;
   unsigned Level;
   bool InPPDirective;
   bool MustBeDeclaration;
-};
+  bool MightBeFunctionDecl;
+
+  /// \c True if this line should be formatted, i.e. intersects directly or
+  /// indirectly with one of the input ranges.
+  bool Affected;
 
-inline prec::Level getPrecedence(const AnnotatedToken &Tok) {
-  return getBinOpPrecedence(Tok.FormatTok.Tok.getKind(), true, true);
-}
+  /// \c True if the leading empty lines of this line intersect with one of the
+  /// input ranges.
+  bool LeadingEmptyLinesAffected;
+
+  /// \c True if a one of this line's children intersects with an input range.
+  bool ChildrenAffected;
+
+private:
+  // Disallow copying.
+  AnnotatedLine(const AnnotatedLine &) LLVM_DELETED_FUNCTION;
+  void operator=(const AnnotatedLine &) LLVM_DELETED_FUNCTION;
+};
 
 /// \brief Determines extra information about the tokens comprising an
 /// \c UnwrappedLine.
 class TokenAnnotator {
 public:
-  TokenAnnotator(const FormatStyle &Style, SourceManager &SourceMgr, Lexer &Lex,
-                 IdentifierInfo &Ident_in)
-      : Style(Style), SourceMgr(SourceMgr), Lex(Lex), Ident_in(Ident_in) {
-  }
+  TokenAnnotator(const FormatStyle &Style, IdentifierInfo &Ident_in)
+      : Style(Style), Ident_in(Ident_in) {}
+
+  /// \brief 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);
 
   void annotate(AnnotatedLine &Line);
   void calculateFormattingInformation(AnnotatedLine &Line);
 
 private:
   /// \brief Calculate the penalty for splitting before \c Tok.
-  unsigned splitPenalty(const AnnotatedLine &Line, const AnnotatedToken &Tok);
+  unsigned splitPenalty(const AnnotatedLine &Line, const FormatToken &Tok,
+                        bool InFunctionDecl);
+
+  bool spaceRequiredBetween(const AnnotatedLine &Line, const FormatToken &Left,
+                            const FormatToken &Right);
+
+  bool spaceRequiredBefore(const AnnotatedLine &Line, const FormatToken &Tok);
+
+  bool mustBreakBefore(const AnnotatedLine &Line, const FormatToken &Right);
 
-  bool spaceRequiredBetween(const AnnotatedLine &Line,
-                            const AnnotatedToken &Left,
-                            const AnnotatedToken &Right);
+  bool canBreakBefore(const AnnotatedLine &Line, const FormatToken &Right);
 
-  bool spaceRequiredBefore(const AnnotatedLine &Line,
-                           const AnnotatedToken &Tok);
+  void printDebugInfo(const AnnotatedLine &Line);
 
-  bool canBreakBefore(const AnnotatedLine &Line, const AnnotatedToken &Right);
+  void calculateUnbreakableTailLengths(AnnotatedLine &Line);
 
   const FormatStyle &Style;
-  SourceManager &SourceMgr;
-  Lexer &Lex;
 
   // Contextual keywords:
   IdentifierInfo &Ident_in;
@@ -211,4 +146,4 @@ private:
 } // end namespace format
 } // end namespace clang
 
-#endif // LLVM_CLANG_FORMAT_TOKEN_ANNOTATOR_H
+#endif