TokenAnnotator.h revision 8ff690ab478b33e0d830a6203de12d191d94f8ff
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/Basic/OperatorPrecedence.h"
2132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper#include "clang/Format/Format.h"
2232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper#include <string>
2332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
2432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jaspernamespace clang {
2532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasperclass Lexer;
2632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasperclass SourceManager;
2732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
2832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jaspernamespace format {
2932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
3032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasperenum TokenType {
3132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  TT_BinaryOperator,
3232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  TT_BlockComment,
3332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  TT_CastRParen,
3432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  TT_ConditionalExpr,
3532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  TT_CtorInitializerColon,
3632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  TT_ImplicitStringLiteral,
3732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  TT_LineComment,
3832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  TT_ObjCBlockLParen,
3932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  TT_ObjCDecl,
4032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  TT_ObjCMethodSpecifier,
4132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  TT_ObjCMethodExpr,
4232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  TT_ObjCProperty,
4363d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper  TT_ObjCSelectorName,
4432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  TT_OverloadedOperator,
4532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  TT_PointerOrReference,
4632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  TT_PureVirtualSpecifier,
4732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  TT_RangeBasedForLoopColon,
4832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  TT_StartOfName,
4932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  TT_TemplateCloser,
5032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  TT_TemplateOpener,
5132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  TT_TrailingUnaryOperator,
5232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  TT_UnaryOperator,
5332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  TT_Unknown
5432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper};
5532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
5632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasperenum LineType {
5732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  LT_Invalid,
5832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  LT_Other,
5932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  LT_BuilderTypeCall,
6032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  LT_PreprocessorDirective,
6132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  LT_VirtualFunctionDecl,
6232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  LT_ObjCDecl, // An @interface, @implementation, or @protocol line.
6332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  LT_ObjCMethodDecl,
6432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  LT_ObjCProperty // An @property line.
6532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper};
6632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
6732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasperclass AnnotatedToken {
6832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasperpublic:
6932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  explicit AnnotatedToken(const FormatToken &FormatTok)
7032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      : FormatTok(FormatTok), Type(TT_Unknown), SpaceRequiredBefore(false),
7132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        CanBreakBefore(false), MustBreakBefore(false),
7232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        ClosesTemplateDeclaration(false), MatchingParen(NULL),
7363d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper        ParameterCount(1), BindingStrength(0), SplitPenalty(0),
7463d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper        LongestObjCSelectorName(0), Parent(NULL) {
7532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  }
7632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
7732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  bool is(tok::TokenKind Kind) const { return FormatTok.Tok.is(Kind); }
7832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  bool isNot(tok::TokenKind Kind) const { return FormatTok.Tok.isNot(Kind); }
7932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
8032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  bool isObjCAtKeyword(tok::ObjCKeywordKind Kind) const {
8132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return FormatTok.Tok.isObjCAtKeyword(Kind);
8232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  }
8332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
8432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  FormatToken FormatTok;
8532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
8632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  TokenType Type;
8732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
8832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  bool SpaceRequiredBefore;
8932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  bool CanBreakBefore;
9032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  bool MustBreakBefore;
9132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
9232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  bool ClosesTemplateDeclaration;
9332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
9432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  AnnotatedToken *MatchingParen;
9532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
9632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  /// \brief Number of parameters, if this is "(", "[" or "<".
9732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  ///
9832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  /// This is initialized to 1 as we don't need to distinguish functions with
9932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  /// 0 parameters from functions with 1 parameter. Thus, we can simply count
10032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  /// the number of commas.
10132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  unsigned ParameterCount;
10232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
10332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  /// \brief The total length of the line up to and including this token.
10432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  unsigned TotalLength;
10532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
1060178673f541685cf5067814dfeee2644078e39a9Daniel Jasper  // FIXME: Come up with a 'cleaner' concept.
1070178673f541685cf5067814dfeee2644078e39a9Daniel Jasper  /// \brief The binding strength of a token. This is a combined value of
1080178673f541685cf5067814dfeee2644078e39a9Daniel Jasper  /// operator precedence, parenthesis nesting, etc.
1090178673f541685cf5067814dfeee2644078e39a9Daniel Jasper  unsigned BindingStrength;
1100178673f541685cf5067814dfeee2644078e39a9Daniel Jasper
11132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  /// \brief Penalty for inserting a line break before this token.
11232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  unsigned SplitPenalty;
11332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
11463d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper  /// \brief If this is the first ObjC selector name in an ObjC method
11563d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper  /// definition or call, this contains the length of the longest name.
11663d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper  unsigned LongestObjCSelectorName;
11763d7cedca8616921c1908c88c2f23fcd67bbab99Daniel Jasper
11832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  std::vector<AnnotatedToken> Children;
11932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  AnnotatedToken *Parent;
12032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
12132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  const AnnotatedToken *getPreviousNoneComment() const {
12232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    AnnotatedToken *Tok = Parent;
12332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    while (Tok != NULL && Tok->is(tok::comment))
12432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      Tok = Tok->Parent;
12532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    return Tok;
12632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  }
12732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper};
12832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
12932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasperclass AnnotatedLine {
13032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasperpublic:
13132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  AnnotatedLine(const UnwrappedLine &Line)
13232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      : First(Line.Tokens.front()), Level(Line.Level),
13332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        InPPDirective(Line.InPPDirective),
13432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        MustBeDeclaration(Line.MustBeDeclaration) {
13532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    assert(!Line.Tokens.empty());
13632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    AnnotatedToken *Current = &First;
13732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    for (std::list<FormatToken>::const_iterator I = ++Line.Tokens.begin(),
13832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper                                                E = Line.Tokens.end();
13932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper         I != E; ++I) {
14032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      Current->Children.push_back(AnnotatedToken(*I));
14132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      Current->Children[0].Parent = Current;
14232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      Current = &Current->Children[0];
14332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    }
14432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    Last = Current;
14532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  }
14632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  AnnotatedLine(const AnnotatedLine &Other)
14732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      : First(Other.First), Type(Other.Type), Level(Other.Level),
14832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        InPPDirective(Other.InPPDirective),
14932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper        MustBeDeclaration(Other.MustBeDeclaration) {
15032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    Last = &First;
15132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    while (!Last->Children.empty()) {
15232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      Last->Children[0].Parent = Last;
15332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper      Last = &Last->Children[0];
15432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper    }
15532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  }
15632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
15732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  AnnotatedToken First;
15832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  AnnotatedToken *Last;
15932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
16032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  LineType Type;
16132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  unsigned Level;
16232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  bool InPPDirective;
16332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  bool MustBeDeclaration;
16432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper};
16532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
16632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasperinline prec::Level getPrecedence(const AnnotatedToken &Tok) {
16732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  return getBinOpPrecedence(Tok.FormatTok.Tok.getKind(), true, true);
16832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper}
16932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
17032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper/// \brief Determines extra information about the tokens comprising an
17132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper/// \c UnwrappedLine.
17232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasperclass TokenAnnotator {
17332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasperpublic:
1748ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper  TokenAnnotator(const FormatStyle &Style, SourceManager &SourceMgr, Lexer &Lex)
1758ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper      : Style(Style), SourceMgr(SourceMgr), Lex(Lex) {
17632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  }
17732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
1788ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper  void annotate(AnnotatedLine &Line);
1798ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper  void calculateFormattingInformation(AnnotatedLine &Line);
18032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
18132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasperprivate:
18232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  /// \brief Calculate the penalty for splitting before \c Tok.
1838ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper  unsigned splitPenalty(const AnnotatedLine &Line, const AnnotatedToken &Tok);
18432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
1858ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper  bool spaceRequiredBetween(const AnnotatedLine &Line,
1868ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper                            const AnnotatedToken &Left,
18732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper                            const AnnotatedToken &Right);
18832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
1898ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper  bool spaceRequiredBefore(const AnnotatedLine &Line,
1908ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper                           const AnnotatedToken &Tok);
19132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
1928ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper  bool canBreakBefore(const AnnotatedLine &Line, const AnnotatedToken &Right);
19332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
1948ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper  const FormatStyle &Style;
19532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  SourceManager &SourceMgr;
19632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper  Lexer &Lex;
19732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper};
19832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
19932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} // end namespace format
20032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} // end namespace clang
20132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper
20232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper#endif // LLVM_CLANG_FORMAT_TOKEN_ANNOTATOR_H
203