blob: 252997f6d8d4aef7504e7346e80e7358a1412529 [file] [log] [blame]
Alexander Kornienko70ce7882013-04-15 14:28:00 +00001//===--- 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:
Alexander Kornienko70ce7882013-04-15 14:28:00 +000070 std::string getNewLineText(unsigned NewLines, unsigned Spaces);
71
72 std::string getNewLineText(unsigned NewLines, unsigned Spaces,
73 unsigned WhitespaceStartColumn);
74
75 /// \brief Structure to store a comment for later layout and alignment.
76 struct StoredComment {
77 FormatToken Tok;
78 unsigned MinColumn;
79 unsigned MaxColumn;
80 unsigned NewLines;
81 unsigned Spaces;
82 bool Untouchable;
83 };
84 SmallVector<StoredComment, 16> Comments;
85 typedef SmallVector<StoredComment, 16>::iterator comment_iterator;
86
87 /// \brief Try to align all stashed comments.
88 void alignComments();
89
90 /// \brief Put all the comments between \p I and \p E into \p Column.
91 void alignComments(comment_iterator I, comment_iterator E, unsigned Column);
92
93 /// \brief Stores \p Text as the replacement for the whitespace in front of
94 /// \p Tok.
95 void storeReplacement(const FormatToken &Tok, const std::string Text);
96
97 SourceManager &SourceMgr;
98 tooling::Replacements Replaces;
99 const FormatStyle &Style;
100};
101
102} // namespace format
103} // namespace clang
104
105#endif // LLVM_CLANG_FORMAT_WHITESPACEMANAGER_H