clang API Documentation
00001 //===--- TokenAnnotator.h - Format C++ code ---------------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 /// 00010 /// \file 00011 /// \brief This file implements a token annotator, i.e. creates 00012 /// \c AnnotatedTokens out of \c FormatTokens with required extra information. 00013 /// 00014 //===----------------------------------------------------------------------===// 00015 00016 #ifndef LLVM_CLANG_LIB_FORMAT_TOKENANNOTATOR_H 00017 #define LLVM_CLANG_LIB_FORMAT_TOKENANNOTATOR_H 00018 00019 #include "UnwrappedLineParser.h" 00020 #include "clang/Format/Format.h" 00021 #include <string> 00022 00023 namespace clang { 00024 class SourceManager; 00025 00026 namespace format { 00027 00028 enum LineType { 00029 LT_Invalid, 00030 LT_Other, 00031 LT_PreprocessorDirective, 00032 LT_VirtualFunctionDecl, 00033 LT_ObjCDecl, // An @interface, @implementation, or @protocol line. 00034 LT_ObjCMethodDecl, 00035 LT_ObjCProperty // An @property line. 00036 }; 00037 00038 class AnnotatedLine { 00039 public: 00040 AnnotatedLine(const UnwrappedLine &Line) 00041 : First(Line.Tokens.front().Tok), Level(Line.Level), 00042 InPPDirective(Line.InPPDirective), 00043 MustBeDeclaration(Line.MustBeDeclaration), MightBeFunctionDecl(false), 00044 Affected(false), LeadingEmptyLinesAffected(false), 00045 ChildrenAffected(false) { 00046 assert(!Line.Tokens.empty()); 00047 00048 // Calculate Next and Previous for all tokens. Note that we must overwrite 00049 // Next and Previous for every token, as previous formatting runs might have 00050 // left them in a different state. 00051 First->Previous = nullptr; 00052 FormatToken *Current = First; 00053 for (std::list<UnwrappedLineNode>::const_iterator I = ++Line.Tokens.begin(), 00054 E = Line.Tokens.end(); 00055 I != E; ++I) { 00056 const UnwrappedLineNode &Node = *I; 00057 Current->Next = I->Tok; 00058 I->Tok->Previous = Current; 00059 Current = Current->Next; 00060 Current->Children.clear(); 00061 for (SmallVectorImpl<UnwrappedLine>::const_iterator 00062 I = Node.Children.begin(), 00063 E = Node.Children.end(); 00064 I != E; ++I) { 00065 Children.push_back(new AnnotatedLine(*I)); 00066 Current->Children.push_back(Children.back()); 00067 } 00068 } 00069 Last = Current; 00070 Last->Next = nullptr; 00071 } 00072 00073 ~AnnotatedLine() { 00074 for (unsigned i = 0, e = Children.size(); i != e; ++i) { 00075 delete Children[i]; 00076 } 00077 } 00078 00079 FormatToken *First; 00080 FormatToken *Last; 00081 00082 SmallVector<AnnotatedLine *, 0> Children; 00083 00084 LineType Type; 00085 unsigned Level; 00086 bool InPPDirective; 00087 bool MustBeDeclaration; 00088 bool MightBeFunctionDecl; 00089 00090 /// \c True if this line should be formatted, i.e. intersects directly or 00091 /// indirectly with one of the input ranges. 00092 bool Affected; 00093 00094 /// \c True if the leading empty lines of this line intersect with one of the 00095 /// input ranges. 00096 bool LeadingEmptyLinesAffected; 00097 00098 /// \c True if a one of this line's children intersects with an input range. 00099 bool ChildrenAffected; 00100 00101 private: 00102 // Disallow copying. 00103 AnnotatedLine(const AnnotatedLine &) LLVM_DELETED_FUNCTION; 00104 void operator=(const AnnotatedLine &) LLVM_DELETED_FUNCTION; 00105 }; 00106 00107 /// \brief Determines extra information about the tokens comprising an 00108 /// \c UnwrappedLine. 00109 class TokenAnnotator { 00110 public: 00111 TokenAnnotator(const FormatStyle &Style, const AdditionalKeywords &Keywords) 00112 : Style(Style), Keywords(Keywords) {} 00113 00114 /// \brief Adapts the indent levels of comment lines to the indent of the 00115 /// subsequent line. 00116 // FIXME: Can/should this be done in the UnwrappedLineParser? 00117 void setCommentLineLevels(SmallVectorImpl<AnnotatedLine *> &Lines); 00118 00119 void annotate(AnnotatedLine &Line); 00120 void calculateFormattingInformation(AnnotatedLine &Line); 00121 00122 private: 00123 /// \brief Calculate the penalty for splitting before \c Tok. 00124 unsigned splitPenalty(const AnnotatedLine &Line, const FormatToken &Tok, 00125 bool InFunctionDecl); 00126 00127 bool spaceRequiredBetween(const AnnotatedLine &Line, const FormatToken &Left, 00128 const FormatToken &Right); 00129 00130 bool spaceRequiredBefore(const AnnotatedLine &Line, const FormatToken &Tok); 00131 00132 bool mustBreakBefore(const AnnotatedLine &Line, const FormatToken &Right); 00133 00134 bool canBreakBefore(const AnnotatedLine &Line, const FormatToken &Right); 00135 00136 void printDebugInfo(const AnnotatedLine &Line); 00137 00138 void calculateUnbreakableTailLengths(AnnotatedLine &Line); 00139 00140 const FormatStyle &Style; 00141 00142 const AdditionalKeywords &Keywords; 00143 }; 00144 00145 } // end namespace format 00146 } // end namespace clang 00147 00148 #endif