diff options
author | Alexander Kornienko <alexfh@google.com> | 2013-04-15 14:28:00 +0000 |
---|---|---|
committer | Alexander Kornienko <alexfh@google.com> | 2013-04-15 14:28:00 +0000 |
commit | 70ce7881fc30a39b795b2873f008e7eca72ba669 (patch) | |
tree | f9190f278da3d6f81517e5f69243d13f3c46f15e /lib/Format/WhitespaceManager.h | |
parent | 115ac5ac1281e6f301da4da6a5c669beae59ffcc (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.h | 120 |
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 |