WhitespaceManager.h revision 70ce7881fc30a39b795b2873f008e7eca72ba669
1//===--- WhitespaceManager.h - Format C++ code ----------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9/// 10/// \file 11/// \brief WhitespaceManager class manages whitespace around tokens and their 12/// replacements. 13/// 14//===----------------------------------------------------------------------===// 15 16#ifndef LLVM_CLANG_FORMAT_WHITESPACEMANAGER_H 17#define LLVM_CLANG_FORMAT_WHITESPACEMANAGER_H 18 19#include "TokenAnnotator.h" 20#include "clang/Basic/SourceManager.h" 21#include "clang/Format/Format.h" 22#include <string> 23 24namespace clang { 25namespace format { 26 27/// \brief Manages the whitespaces around tokens and their replacements. 28/// 29/// This includes special handling for certain constructs, e.g. the alignment of 30/// trailing line comments. 31class WhitespaceManager { 32public: 33 WhitespaceManager(SourceManager &SourceMgr, const FormatStyle &Style) 34 : SourceMgr(SourceMgr), Style(Style) {} 35 36 /// \brief Replaces the whitespace in front of \p Tok. Only call once for 37 /// each \c AnnotatedToken. 38 void replaceWhitespace(const AnnotatedToken &Tok, unsigned NewLines, 39 unsigned Spaces, unsigned WhitespaceStartColumn); 40 41 /// \brief Like \c replaceWhitespace, but additionally adds right-aligned 42 /// backslashes to escape newlines inside a preprocessor directive. 43 /// 44 /// This function and \c replaceWhitespace have the same behavior if 45 /// \c Newlines == 0. 46 void replacePPWhitespace(const AnnotatedToken &Tok, unsigned NewLines, 47 unsigned Spaces, unsigned WhitespaceStartColumn); 48 49 /// \brief Inserts a line break into the middle of a token. 50 /// 51 /// Will break at \p Offset inside \p Tok, putting \p Prefix before the line 52 /// break and \p Postfix before the rest of the token starts in the next line. 53 /// 54 /// \p InPPDirective, \p Spaces, \p WhitespaceStartColumn and \p Style are 55 /// used to generate the correct line break. 56 void breakToken(const FormatToken &Tok, unsigned Offset, 57 unsigned ReplaceChars, StringRef Prefix, StringRef Postfix, 58 bool InPPDirective, unsigned Spaces, 59 unsigned WhitespaceStartColumn); 60 61 /// \brief Returns all the \c Replacements created during formatting. 62 const tooling::Replacements &generateReplacements(); 63 64 void addReplacement(const SourceLocation &SourceLoc, unsigned ReplaceChars, 65 StringRef Text); 66 67 void addUntouchableComment(unsigned Column); 68 69private: 70 static StringRef getLineCommentPrefix(StringRef Comment); 71 72 /// \brief Splits one line in a line comment, if it doesn't fit to 73 /// provided column limit. Removes trailing whitespace in each line. 74 /// 75 /// \param Line points to the line contents without leading // or /*. 76 /// 77 /// \param StartColumn is the column where the first character of Line will be 78 /// located after formatting. 79 /// 80 /// \param LinePrefix is inserted after each line break. 81 void splitLineComment(const FormatToken &Tok, StringRef Line, 82 size_t StartColumn, StringRef LinePrefix, 83 const char *WhiteSpaceChars = " "); 84 85 std::string getNewLineText(unsigned NewLines, unsigned Spaces); 86 87 std::string getNewLineText(unsigned NewLines, unsigned Spaces, 88 unsigned WhitespaceStartColumn); 89 90 /// \brief Structure to store a comment for later layout and alignment. 91 struct StoredComment { 92 FormatToken Tok; 93 unsigned MinColumn; 94 unsigned MaxColumn; 95 unsigned NewLines; 96 unsigned Spaces; 97 bool Untouchable; 98 }; 99 SmallVector<StoredComment, 16> Comments; 100 typedef SmallVector<StoredComment, 16>::iterator comment_iterator; 101 102 /// \brief Try to align all stashed comments. 103 void alignComments(); 104 105 /// \brief Put all the comments between \p I and \p E into \p Column. 106 void alignComments(comment_iterator I, comment_iterator E, unsigned Column); 107 108 /// \brief Stores \p Text as the replacement for the whitespace in front of 109 /// \p Tok. 110 void storeReplacement(const FormatToken &Tok, const std::string Text); 111 112 SourceManager &SourceMgr; 113 tooling::Replacements Replaces; 114 const FormatStyle &Style; 115}; 116 117} // namespace format 118} // namespace clang 119 120#endif // LLVM_CLANG_FORMAT_WHITESPACEMANAGER_H 121