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