1251609Sdim//===--- WhitespaceManager.h - Format C++ code ------------------*- C++ -*-===// 2251609Sdim// 3251609Sdim// The LLVM Compiler Infrastructure 4251609Sdim// 5251609Sdim// This file is distributed under the University of Illinois Open Source 6251609Sdim// License. See LICENSE.TXT for details. 7251609Sdim// 8251609Sdim//===----------------------------------------------------------------------===// 9251609Sdim/// 10251609Sdim/// \file 11251609Sdim/// \brief WhitespaceManager class manages whitespace around tokens and their 12251609Sdim/// replacements. 13251609Sdim/// 14251609Sdim//===----------------------------------------------------------------------===// 15251609Sdim 16251609Sdim#ifndef LLVM_CLANG_FORMAT_WHITESPACEMANAGER_H 17251609Sdim#define LLVM_CLANG_FORMAT_WHITESPACEMANAGER_H 18251609Sdim 19251609Sdim#include "TokenAnnotator.h" 20251609Sdim#include "clang/Basic/SourceManager.h" 21251609Sdim#include "clang/Format/Format.h" 22251609Sdim#include <string> 23251609Sdim 24251609Sdimnamespace clang { 25251609Sdimnamespace format { 26251609Sdim 27251609Sdim/// \brief Manages the whitespaces around tokens and their replacements. 28251609Sdim/// 29251609Sdim/// This includes special handling for certain constructs, e.g. the alignment of 30251609Sdim/// trailing line comments. 31251609Sdimclass WhitespaceManager { 32251609Sdimpublic: 33251609Sdim WhitespaceManager(SourceManager &SourceMgr, const FormatStyle &Style) 34251609Sdim : SourceMgr(SourceMgr), Style(Style) {} 35251609Sdim 36251609Sdim /// \brief Replaces the whitespace in front of \p Tok. Only call once for 37251609Sdim /// each \c AnnotatedToken. 38251609Sdim void replaceWhitespace(const AnnotatedToken &Tok, unsigned NewLines, 39251609Sdim unsigned Spaces, unsigned WhitespaceStartColumn); 40251609Sdim 41251609Sdim /// \brief Like \c replaceWhitespace, but additionally adds right-aligned 42251609Sdim /// backslashes to escape newlines inside a preprocessor directive. 43251609Sdim /// 44251609Sdim /// This function and \c replaceWhitespace have the same behavior if 45251609Sdim /// \c Newlines == 0. 46251609Sdim void replacePPWhitespace(const AnnotatedToken &Tok, unsigned NewLines, 47251609Sdim unsigned Spaces, unsigned WhitespaceStartColumn); 48251609Sdim 49251609Sdim /// \brief Inserts a line break into the middle of a token. 50251609Sdim /// 51251609Sdim /// Will break at \p Offset inside \p Tok, putting \p Prefix before the line 52251609Sdim /// break and \p Postfix before the rest of the token starts in the next line. 53251609Sdim /// 54251609Sdim /// \p InPPDirective, \p Spaces, \p WhitespaceStartColumn and \p Style are 55251609Sdim /// used to generate the correct line break. 56251609Sdim void breakToken(const FormatToken &Tok, unsigned Offset, 57251609Sdim unsigned ReplaceChars, StringRef Prefix, StringRef Postfix, 58251609Sdim bool InPPDirective, unsigned Spaces, 59251609Sdim unsigned WhitespaceStartColumn); 60251609Sdim 61251609Sdim /// \brief Returns all the \c Replacements created during formatting. 62251609Sdim const tooling::Replacements &generateReplacements(); 63251609Sdim 64251609Sdim void addReplacement(const SourceLocation &SourceLoc, unsigned ReplaceChars, 65251609Sdim StringRef Text); 66251609Sdim 67251609Sdim void addUntouchableComment(unsigned Column); 68251609Sdim 69251609Sdim /// \brief Try to align all stashed comments. 70251609Sdim void alignComments(); 71251609Sdim /// \brief Try to align all stashed escaped newlines. 72251609Sdim void alignEscapedNewlines(); 73251609Sdim 74251609Sdimprivate: 75251609Sdim std::string getNewLineText(unsigned NewLines, unsigned Spaces); 76251609Sdim 77251609Sdim std::string getNewLineText(unsigned NewLines, unsigned Spaces, 78251609Sdim unsigned WhitespaceStartColumn, 79251609Sdim unsigned EscapedNewlineColumn); 80251609Sdim 81251609Sdim /// \brief Structure to store tokens for later layout and alignment. 82251609Sdim struct StoredToken { 83251609Sdim StoredToken(SourceLocation ReplacementLoc, unsigned ReplacementLength, 84251609Sdim unsigned MinColumn, unsigned MaxColumn, unsigned NewLines, 85251609Sdim unsigned Spaces) 86251609Sdim : ReplacementLoc(ReplacementLoc), ReplacementLength(ReplacementLength), 87251609Sdim MinColumn(MinColumn), MaxColumn(MaxColumn), NewLines(NewLines), 88251609Sdim Spaces(Spaces), Untouchable(false) {} 89251609Sdim SourceLocation ReplacementLoc; 90251609Sdim unsigned ReplacementLength; 91251609Sdim unsigned MinColumn; 92251609Sdim unsigned MaxColumn; 93251609Sdim unsigned NewLines; 94251609Sdim unsigned Spaces; 95251609Sdim bool Untouchable; 96251609Sdim std::string Prefix; 97251609Sdim std::string Postfix; 98251609Sdim }; 99251609Sdim SmallVector<StoredToken, 16> Comments; 100251609Sdim SmallVector<StoredToken, 16> EscapedNewlines; 101251609Sdim typedef SmallVector<StoredToken, 16>::iterator token_iterator; 102251609Sdim 103251609Sdim /// \brief Put all the comments between \p I and \p E into \p Column. 104251609Sdim void alignComments(token_iterator I, token_iterator E, unsigned Column); 105251609Sdim 106251609Sdim /// \brief Stores \p Text as the replacement for the whitespace in front of 107251609Sdim /// \p Tok. 108251609Sdim void storeReplacement(SourceLocation Loc, unsigned Length, 109251609Sdim const std::string Text); 110251609Sdim 111251609Sdim SourceManager &SourceMgr; 112251609Sdim tooling::Replacements Replaces; 113251609Sdim const FormatStyle &Style; 114251609Sdim}; 115251609Sdim 116251609Sdim} // namespace format 117251609Sdim} // namespace clang 118251609Sdim 119251609Sdim#endif // LLVM_CLANG_FORMAT_WHITESPACEMANAGER_H 120