1249261Sdim//===--- TokenAnnotator.h - Format C++ code ---------------------*- C++ -*-===// 2249261Sdim// 3249261Sdim// The LLVM Compiler Infrastructure 4249261Sdim// 5249261Sdim// This file is distributed under the University of Illinois Open Source 6249261Sdim// License. See LICENSE.TXT for details. 7249261Sdim// 8249261Sdim//===----------------------------------------------------------------------===// 9249261Sdim/// 10249261Sdim/// \file 11249261Sdim/// \brief This file implements a token annotator, i.e. creates 12249261Sdim/// \c AnnotatedTokens out of \c FormatTokens with required extra information. 13249261Sdim/// 14249261Sdim//===----------------------------------------------------------------------===// 15249261Sdim 16249261Sdim#ifndef LLVM_CLANG_FORMAT_TOKEN_ANNOTATOR_H 17249261Sdim#define LLVM_CLANG_FORMAT_TOKEN_ANNOTATOR_H 18249261Sdim 19249261Sdim#include "UnwrappedLineParser.h" 20249261Sdim#include "clang/Format/Format.h" 21249261Sdim#include <string> 22249261Sdim 23249261Sdimnamespace clang { 24249261Sdimclass SourceManager; 25249261Sdim 26249261Sdimnamespace format { 27249261Sdim 28249261Sdimenum LineType { 29249261Sdim LT_Invalid, 30249261Sdim LT_Other, 31249261Sdim LT_PreprocessorDirective, 32249261Sdim LT_VirtualFunctionDecl, 33249261Sdim LT_ObjCDecl, // An @interface, @implementation, or @protocol line. 34249261Sdim LT_ObjCMethodDecl, 35249261Sdim LT_ObjCProperty // An @property line. 36249261Sdim}; 37249261Sdim 38249261Sdimclass AnnotatedLine { 39249261Sdimpublic: 40249261Sdim AnnotatedLine(const UnwrappedLine &Line) 41263509Sdim : First(Line.Tokens.front().Tok), Level(Line.Level), 42249261Sdim InPPDirective(Line.InPPDirective), 43252723Sdim MustBeDeclaration(Line.MustBeDeclaration), MightBeFunctionDecl(false), 44252723Sdim StartsDefinition(false) { 45249261Sdim assert(!Line.Tokens.empty()); 46263509Sdim 47263509Sdim // Calculate Next and Previous for all tokens. Note that we must overwrite 48263509Sdim // Next and Previous for every token, as previous formatting runs might have 49263509Sdim // left them in a different state. 50263509Sdim First->Previous = NULL; 51263509Sdim FormatToken *Current = First; 52263509Sdim for (std::list<UnwrappedLineNode>::const_iterator I = ++Line.Tokens.begin(), 53263509Sdim E = Line.Tokens.end(); 54249261Sdim I != E; ++I) { 55263509Sdim const UnwrappedLineNode &Node = *I; 56263509Sdim Current->Next = I->Tok; 57263509Sdim I->Tok->Previous = Current; 58263509Sdim Current = Current->Next; 59263509Sdim Current->Children.clear(); 60263509Sdim for (SmallVectorImpl<UnwrappedLine>::const_iterator 61263509Sdim I = Node.Children.begin(), 62263509Sdim E = Node.Children.end(); 63263509Sdim I != E; ++I) { 64263509Sdim Children.push_back(new AnnotatedLine(*I)); 65263509Sdim Current->Children.push_back(Children.back()); 66263509Sdim } 67249261Sdim } 68249261Sdim Last = Current; 69263509Sdim Last->Next = NULL; 70249261Sdim } 71263509Sdim 72263509Sdim ~AnnotatedLine() { 73263509Sdim for (unsigned i = 0, e = Children.size(); i != e; ++i) { 74263509Sdim delete Children[i]; 75249261Sdim } 76249261Sdim } 77249261Sdim 78263509Sdim FormatToken *First; 79263509Sdim FormatToken *Last; 80249261Sdim 81263509Sdim SmallVector<AnnotatedLine *, 0> Children; 82263509Sdim 83249261Sdim LineType Type; 84249261Sdim unsigned Level; 85249261Sdim bool InPPDirective; 86249261Sdim bool MustBeDeclaration; 87249261Sdim bool MightBeFunctionDecl; 88252723Sdim bool StartsDefinition; 89263509Sdim 90263509Sdimprivate: 91263509Sdim // Disallow copying. 92263509Sdim AnnotatedLine(const AnnotatedLine &) LLVM_DELETED_FUNCTION; 93263509Sdim void operator=(const AnnotatedLine &) LLVM_DELETED_FUNCTION; 94249261Sdim}; 95249261Sdim 96249261Sdim/// \brief Determines extra information about the tokens comprising an 97249261Sdim/// \c UnwrappedLine. 98249261Sdimclass TokenAnnotator { 99249261Sdimpublic: 100263509Sdim TokenAnnotator(const FormatStyle &Style, IdentifierInfo &Ident_in) 101263509Sdim : Style(Style), Ident_in(Ident_in) {} 102249261Sdim 103263509Sdim /// \brief Adapts the indent levels of comment lines to the indent of the 104263509Sdim /// subsequent line. 105263509Sdim // FIXME: Can/should this be done in the UnwrappedLineParser? 106263509Sdim void setCommentLineLevels(SmallVectorImpl<AnnotatedLine *> &Lines); 107263509Sdim 108249261Sdim void annotate(AnnotatedLine &Line); 109249261Sdim void calculateFormattingInformation(AnnotatedLine &Line); 110249261Sdim 111249261Sdimprivate: 112249261Sdim /// \brief Calculate the penalty for splitting before \c Tok. 113263509Sdim unsigned splitPenalty(const AnnotatedLine &Line, const FormatToken &Tok, 114263509Sdim bool InFunctionDecl); 115249261Sdim 116263509Sdim bool spaceRequiredBetween(const AnnotatedLine &Line, const FormatToken &Left, 117263509Sdim const FormatToken &Right); 118249261Sdim 119263509Sdim bool spaceRequiredBefore(const AnnotatedLine &Line, const FormatToken &Tok); 120249261Sdim 121263509Sdim bool mustBreakBefore(const AnnotatedLine &Line, const FormatToken &Right); 122249261Sdim 123263509Sdim bool canBreakBefore(const AnnotatedLine &Line, const FormatToken &Right); 124263509Sdim 125252723Sdim void printDebugInfo(const AnnotatedLine &Line); 126252723Sdim 127263509Sdim void calculateUnbreakableTailLengths(AnnotatedLine &Line); 128263509Sdim 129249261Sdim const FormatStyle &Style; 130249261Sdim 131249261Sdim // Contextual keywords: 132249261Sdim IdentifierInfo &Ident_in; 133249261Sdim}; 134249261Sdim 135249261Sdim} // end namespace format 136249261Sdim} // end namespace clang 137249261Sdim 138249261Sdim#endif // LLVM_CLANG_FORMAT_TOKEN_ANNOTATOR_H 139