aboutsummaryrefslogtreecommitdiff
path: root/lib/Format/WhitespaceManager.h
diff options
context:
space:
mode:
authorAlexander Kornienko <alexfh@google.com>2013-04-15 14:28:00 +0000
committerAlexander Kornienko <alexfh@google.com>2013-04-15 14:28:00 +0000
commit70ce7881fc30a39b795b2873f008e7eca72ba669 (patch)
treef9190f278da3d6f81517e5f69243d13f3c46f15e /lib/Format/WhitespaceManager.h
parent115ac5ac1281e6f301da4da6a5c669beae59ffcc (diff)
Unified token breaking logic for strings and block comments.
Summary: Both strings and block comments are broken into lines in breakProtrudingToken. Logic specific for strings or block comments is abstracted in implementations of the BreakToken interface. Among other goodness, this change fixes placement of backslashes after a block comment inside a preprocessor directive (see removed FIXMEs in unit tests). The code is far from being polished, and some parts of it will be changed for line comments support. Reviewers: klimek Reviewed By: klimek CC: cfe-commits Differential Revision: http://llvm-reviews.chandlerc.com/D665 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179526 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Format/WhitespaceManager.h')
-rw-r--r--lib/Format/WhitespaceManager.h120
1 files changed, 120 insertions, 0 deletions
diff --git a/lib/Format/WhitespaceManager.h b/lib/Format/WhitespaceManager.h
new file mode 100644
index 0000000000..d880069595
--- /dev/null
+++ b/lib/Format/WhitespaceManager.h
@@ -0,0 +1,120 @@
+//===--- WhitespaceManager.h - Format C++ code ----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief WhitespaceManager class manages whitespace around tokens and their
+/// replacements.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FORMAT_WHITESPACEMANAGER_H
+#define LLVM_CLANG_FORMAT_WHITESPACEMANAGER_H
+
+#include "TokenAnnotator.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Format/Format.h"
+#include <string>
+
+namespace clang {
+namespace format {
+
+/// \brief Manages the whitespaces around tokens and their replacements.
+///
+/// This includes special handling for certain constructs, e.g. the alignment of
+/// trailing line comments.
+class WhitespaceManager {
+public:
+ WhitespaceManager(SourceManager &SourceMgr, const FormatStyle &Style)
+ : SourceMgr(SourceMgr), Style(Style) {}
+
+ /// \brief Replaces the whitespace in front of \p Tok. Only call once for
+ /// each \c AnnotatedToken.
+ void replaceWhitespace(const AnnotatedToken &Tok, unsigned NewLines,
+ unsigned Spaces, unsigned WhitespaceStartColumn);
+
+ /// \brief Like \c replaceWhitespace, but additionally adds right-aligned
+ /// backslashes to escape newlines inside a preprocessor directive.
+ ///
+ /// This function and \c replaceWhitespace have the same behavior if
+ /// \c Newlines == 0.
+ void replacePPWhitespace(const AnnotatedToken &Tok, unsigned NewLines,
+ unsigned Spaces, unsigned WhitespaceStartColumn);
+
+ /// \brief Inserts a line break into the middle of a token.
+ ///
+ /// Will break at \p Offset inside \p Tok, putting \p Prefix before the line
+ /// break and \p Postfix before the rest of the token starts in the next line.
+ ///
+ /// \p InPPDirective, \p Spaces, \p WhitespaceStartColumn and \p Style are
+ /// used to generate the correct line break.
+ void breakToken(const FormatToken &Tok, unsigned Offset,
+ unsigned ReplaceChars, StringRef Prefix, StringRef Postfix,
+ bool InPPDirective, unsigned Spaces,
+ unsigned WhitespaceStartColumn);
+
+ /// \brief Returns all the \c Replacements created during formatting.
+ const tooling::Replacements &generateReplacements();
+
+ void addReplacement(const SourceLocation &SourceLoc, unsigned ReplaceChars,
+ StringRef Text);
+
+ void addUntouchableComment(unsigned Column);
+
+private:
+ static StringRef getLineCommentPrefix(StringRef Comment);
+
+ /// \brief Splits one line in a line comment, if it doesn't fit to
+ /// provided column limit. Removes trailing whitespace in each line.
+ ///
+ /// \param Line points to the line contents without leading // or /*.
+ ///
+ /// \param StartColumn is the column where the first character of Line will be
+ /// located after formatting.
+ ///
+ /// \param LinePrefix is inserted after each line break.
+ void splitLineComment(const FormatToken &Tok, StringRef Line,
+ size_t StartColumn, StringRef LinePrefix,
+ const char *WhiteSpaceChars = " ");
+
+ std::string getNewLineText(unsigned NewLines, unsigned Spaces);
+
+ std::string getNewLineText(unsigned NewLines, unsigned Spaces,
+ unsigned WhitespaceStartColumn);
+
+ /// \brief Structure to store a comment for later layout and alignment.
+ struct StoredComment {
+ FormatToken Tok;
+ unsigned MinColumn;
+ unsigned MaxColumn;
+ unsigned NewLines;
+ unsigned Spaces;
+ bool Untouchable;
+ };
+ SmallVector<StoredComment, 16> Comments;
+ typedef SmallVector<StoredComment, 16>::iterator comment_iterator;
+
+ /// \brief Try to align all stashed comments.
+ void alignComments();
+
+ /// \brief Put all the comments between \p I and \p E into \p Column.
+ void alignComments(comment_iterator I, comment_iterator E, unsigned Column);
+
+ /// \brief Stores \p Text as the replacement for the whitespace in front of
+ /// \p Tok.
+ void storeReplacement(const FormatToken &Tok, const std::string Text);
+
+ SourceManager &SourceMgr;
+ tooling::Replacements Replaces;
+ const FormatStyle &Style;
+};
+
+} // namespace format
+} // namespace clang
+
+#endif // LLVM_CLANG_FORMAT_WHITESPACEMANAGER_H