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/Format/Format.h" 2132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper#include <string> 2232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 2332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jaspernamespace clang { 2432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasperclass SourceManager; 2532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 2632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jaspernamespace format { 2732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 2832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasperenum LineType { 2932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper LT_Invalid, 3032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper LT_Other, 3132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper LT_PreprocessorDirective, 3232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper LT_VirtualFunctionDecl, 3332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper LT_ObjCDecl, // An @interface, @implementation, or @protocol line. 3432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper LT_ObjCMethodDecl, 3532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper LT_ObjCProperty // An @property line. 3632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper}; 3732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 3832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasperclass AnnotatedLine { 3932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasperpublic: 4032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper AnnotatedLine(const UnwrappedLine &Line) 41567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper : First(Line.Tokens.front().Tok), Level(Line.Level), 4232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper InPPDirective(Line.InPPDirective), 4353e72cdcc0bc217cab33fa56858a0fe5b94ca453Daniel Jasper MustBeDeclaration(Line.MustBeDeclaration), MightBeFunctionDecl(false), 44ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Affected(false), LeadingEmptyLinesAffected(false), 45ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ChildrenAffected(false) { 4632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper assert(!Line.Tokens.empty()); 47d186f0b4c15d4c63e0ae7fbe6ca3207871ba2eb9Manuel Klimek 48d186f0b4c15d4c63e0ae7fbe6ca3207871ba2eb9Manuel Klimek // Calculate Next and Previous for all tokens. Note that we must overwrite 49d186f0b4c15d4c63e0ae7fbe6ca3207871ba2eb9Manuel Klimek // Next and Previous for every token, as previous formatting runs might have 50d186f0b4c15d4c63e0ae7fbe6ca3207871ba2eb9Manuel Klimek // left them in a different state. 516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines First->Previous = nullptr; 52b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek FormatToken *Current = First; 53567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper for (std::list<UnwrappedLineNode>::const_iterator I = ++Line.Tokens.begin(), 54567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper E = Line.Tokens.end(); 5532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper I != E; ++I) { 56567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper const UnwrappedLineNode &Node = *I; 57567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper Current->Next = I->Tok; 58567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper I->Tok->Previous = Current; 59b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek Current = Current->Next; 60852bce4ba3c59669a80d4755f07782a3c28c606bDaniel Jasper Current->Children.clear(); 61567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper for (SmallVectorImpl<UnwrappedLine>::const_iterator 62567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper I = Node.Children.begin(), 63567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper E = Node.Children.end(); 64567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper I != E; ++I) { 65567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper Children.push_back(new AnnotatedLine(*I)); 66567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper Current->Children.push_back(Children.back()); 67567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper } 6832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 6932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper Last = Current; 706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Last->Next = nullptr; 7132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper } 7232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 73567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper ~AnnotatedLine() { 74567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper for (unsigned i = 0, e = Children.size(); i != e; ++i) { 75567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper delete Children[i]; 76567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper } 77567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper } 78567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper 79b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek FormatToken *First; 80b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek FormatToken *Last; 8132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 82b77d741691a2775b5c31e29f021203cc659c26dfDaniel Jasper SmallVector<AnnotatedLine *, 0> Children; 83567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper 8432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper LineType Type; 8532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper unsigned Level; 8632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool InPPDirective; 8732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper bool MustBeDeclaration; 883c08a818a6ac9115fe8880af9bbf5a0a87bdffaaDaniel Jasper bool MightBeFunctionDecl; 89567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper 90651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// \c True if this line should be formatted, i.e. intersects directly or 91651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// indirectly with one of the input ranges. 92651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool Affected; 93651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 94651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// \c True if the leading empty lines of this line intersect with one of the 95651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// input ranges. 96651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool LeadingEmptyLinesAffected; 97651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 98651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// \c True if a one of this line's children intersects with an input range. 99651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool ChildrenAffected; 100651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 101567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasperprivate: 102567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper // Disallow copying. 103567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper AnnotatedLine(const AnnotatedLine &) LLVM_DELETED_FUNCTION; 104567dcf95424d69657f75e4bfd028967ca1f9eb8dDaniel Jasper void operator=(const AnnotatedLine &) LLVM_DELETED_FUNCTION; 10532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper}; 10632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 10732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper/// \brief Determines extra information about the tokens comprising an 10832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper/// \c UnwrappedLine. 10932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasperclass TokenAnnotator { 11032d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasperpublic: 11100895106f9ed602af67984ec4d225a0cdc8c12afAlexander Kornienko TokenAnnotator(const FormatStyle &Style, IdentifierInfo &Ident_in) 11200895106f9ed602af67984ec4d225a0cdc8c12afAlexander Kornienko : Style(Style), Ident_in(Ident_in) {} 11332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 114b77d741691a2775b5c31e29f021203cc659c26dfDaniel Jasper /// \brief Adapts the indent levels of comment lines to the indent of the 115b77d741691a2775b5c31e29f021203cc659c26dfDaniel Jasper /// subsequent line. 116b77d741691a2775b5c31e29f021203cc659c26dfDaniel Jasper // FIXME: Can/should this be done in the UnwrappedLineParser? 117b77d741691a2775b5c31e29f021203cc659c26dfDaniel Jasper void setCommentLineLevels(SmallVectorImpl<AnnotatedLine *> &Lines); 118b77d741691a2775b5c31e29f021203cc659c26dfDaniel Jasper 1198ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper void annotate(AnnotatedLine &Line); 1208ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper void calculateFormattingInformation(AnnotatedLine &Line); 12132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 12232d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasperprivate: 12332d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper /// \brief Calculate the penalty for splitting before \c Tok. 124dbfb5f37f4d003ae6935b87a103b7827d5069690Daniel Jasper unsigned splitPenalty(const AnnotatedLine &Line, const FormatToken &Tok, 125dbfb5f37f4d003ae6935b87a103b7827d5069690Daniel Jasper bool InFunctionDecl); 12632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 127b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek bool spaceRequiredBetween(const AnnotatedLine &Line, const FormatToken &Left, 128b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek const FormatToken &Right); 12932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 130b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek bool spaceRequiredBefore(const AnnotatedLine &Line, const FormatToken &Tok); 13132d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 132ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper bool mustBreakBefore(const AnnotatedLine &Line, const FormatToken &Right); 133ebaa1719fdd180e6dd9b4e6471e83500471a2f16Daniel Jasper 134b398701e4cbb9a55d90a60e3f4f4bc577446d098Manuel Klimek bool canBreakBefore(const AnnotatedLine &Line, const FormatToken &Right); 13532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 136bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper void printDebugInfo(const AnnotatedLine &Line); 137bf71ba2988b34c45af968f0965e28ac952e4a15fDaniel Jasper 138e573c3f7fc40e813559ab4ff1e7eec4f66f1a50fManuel Klimek void calculateUnbreakableTailLengths(AnnotatedLine &Line); 139e573c3f7fc40e813559ab4ff1e7eec4f66f1a50fManuel Klimek 1408ff690ab478b33e0d830a6203de12d191d94f8ffDaniel Jasper const FormatStyle &Style; 141c2e6d2a4a7fe9dfa7d52a38c6048b7b18e6b591aNico Weber 142c2e6d2a4a7fe9dfa7d52a38c6048b7b18e6b591aNico Weber // Contextual keywords: 143c2e6d2a4a7fe9dfa7d52a38c6048b7b18e6b591aNico Weber IdentifierInfo &Ident_in; 14432d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper}; 14532d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 14632d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} // end namespace format 14732d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper} // end namespace clang 14832d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper 14932d28ee6061930b2a9c170cbaaeea028c88a7b89Daniel Jasper#endif // LLVM_CLANG_FORMAT_TOKEN_ANNOTATOR_H 150