diff options
Diffstat (limited to 'lib/Format/ContinuationIndenter.h')
-rw-r--r-- | lib/Format/ContinuationIndenter.h | 75 |
1 files changed, 65 insertions, 10 deletions
diff --git a/lib/Format/ContinuationIndenter.h b/lib/Format/ContinuationIndenter.h index 9a06aa6f6267..ded7bfab4267 100644 --- a/lib/Format/ContinuationIndenter.h +++ b/lib/Format/ContinuationIndenter.h @@ -20,6 +20,8 @@ #include "FormatToken.h" #include "clang/Format/Format.h" #include "llvm/Support/Regex.h" +#include <map> +#include <tuple> namespace clang { class SourceManager; @@ -27,11 +29,21 @@ class SourceManager; namespace format { class AnnotatedLine; +class BreakableToken; struct FormatToken; struct LineState; struct ParenState; +struct RawStringFormatStyleManager; class WhitespaceManager; +struct RawStringFormatStyleManager { + llvm::StringMap<FormatStyle> DelimiterStyle; + + RawStringFormatStyleManager(const FormatStyle &CodeStyle); + + llvm::Optional<FormatStyle> get(StringRef Delimiter) const; +}; + class ContinuationIndenter { public: /// \brief Constructs a \c ContinuationIndenter to format \p Line starting in @@ -44,9 +56,11 @@ public: bool BinPackInconclusiveFunctions); /// \brief Get the initial state, i.e. the state after placing \p Line's - /// first token at \p FirstIndent. - LineState getInitialState(unsigned FirstIndent, const AnnotatedLine *Line, - bool DryRun); + /// first token at \p FirstIndent. When reformatting a fragment of code, as in + /// the case of formatting inside raw string literals, \p FirstStartColumn is + /// the column at which the state of the parent formatter is. + LineState getInitialState(unsigned FirstIndent, unsigned FirstStartColumn, + const AnnotatedLine *Line, bool DryRun); // FIXME: canBreak and mustBreak aren't strictly indentation-related. Find a // better home. @@ -88,17 +102,52 @@ private: /// \brief Update 'State' with the next token opening a nested block. void moveStateToNewBlock(LineState &State); + /// \brief Reformats a raw string literal. + /// + /// \returns An extra penalty induced by reformatting the token. + unsigned reformatRawStringLiteral(const FormatToken &Current, + LineState &State, + const FormatStyle &RawStringStyle, + bool DryRun); + + /// \brief If the current token is at the end of the current line, handle + /// the transition to the next line. + unsigned handleEndOfLine(const FormatToken &Current, LineState &State, + bool DryRun, bool AllowBreak); + + /// \brief If \p Current is a raw string that is configured to be reformatted, + /// return the style to be used. + llvm::Optional<FormatStyle> getRawStringStyle(const FormatToken &Current, + const LineState &State); + /// \brief If the current token sticks out over the end of the line, break /// it if possible. /// - /// \returns An extra penalty if a token was broken, otherwise 0. + /// \returns A pair (penalty, exceeded), where penalty is the extra penalty + /// when tokens are broken or lines exceed the column limit, and exceeded + /// indicates whether the algorithm purposefully left lines exceeding the + /// column limit. /// - /// The returned penalty will cover the cost of the additional line breaks and - /// column limit violation in all lines except for the last one. The penalty - /// for the column limit violation in the last line (and in single line - /// tokens) is handled in \c addNextStateToQueue. - unsigned breakProtrudingToken(const FormatToken &Current, LineState &State, - bool DryRun); + /// The returned penalty will cover the cost of the additional line breaks + /// and column limit violation in all lines except for the last one. The + /// penalty for the column limit violation in the last line (and in single + /// line tokens) is handled in \c addNextStateToQueue. + /// + /// \p Strict indicates whether reflowing is allowed to leave characters + /// protruding the column limit; if true, lines will be split strictly within + /// the column limit where possible; if false, words are allowed to protrude + /// over the column limit as long as the penalty is less than the penalty + /// of a break. + std::pair<unsigned, bool> breakProtrudingToken(const FormatToken &Current, + LineState &State, + bool AllowBreak, bool DryRun, + bool Strict); + + /// \brief Returns the \c BreakableToken starting at \p Current, or nullptr + /// if the current token cannot be broken. + std::unique_ptr<BreakableToken> + createBreakableToken(const FormatToken &Current, LineState &State, + bool AllowBreak); /// \brief Appends the next token to \p State and updates information /// necessary for indentation. @@ -143,6 +192,7 @@ private: encoding::Encoding Encoding; bool BinPackInconclusiveFunctions; llvm::Regex CommentPragmasRegex; + const RawStringFormatStyleManager RawStringFormats; }; struct ParenState { @@ -318,6 +368,9 @@ struct LineState { /// \brief \c true if this line contains a continued for-loop section. bool LineContainsContinuedForLoopSection; + /// \brief \c true if \p NextToken should not continue this line. + bool NoContinuation; + /// \brief The \c NestingLevel at the start of this line. unsigned StartOfLineLevel; @@ -364,6 +417,8 @@ struct LineState { if (LineContainsContinuedForLoopSection != Other.LineContainsContinuedForLoopSection) return LineContainsContinuedForLoopSection; + if (NoContinuation != Other.NoContinuation) + return NoContinuation; if (StartOfLineLevel != Other.StartOfLineLevel) return StartOfLineLevel < Other.StartOfLineLevel; if (LowestLevelOnLine != Other.LowestLevelOnLine) |