170ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko//===--- BreakableToken.h - Format C++ code -------------------------------===//
270ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko//
370ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko//                     The LLVM Compiler Infrastructure
470ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko//
570ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko// This file is distributed under the University of Illinois Open Source
670ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko// License. See LICENSE.TXT for details.
770ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko//
870ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko//===----------------------------------------------------------------------===//
970ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko///
1070ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko/// \file
1170ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko/// \brief Declares BreakableToken, BreakableStringLiteral, and
1270ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko/// BreakableBlockComment classes, that contain token type-specific logic to
1370ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko/// break long lines in tokens.
1470ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko///
1570ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko//===----------------------------------------------------------------------===//
1670ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
1770ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko#ifndef LLVM_CLANG_FORMAT_BREAKABLETOKEN_H
1870ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko#define LLVM_CLANG_FORMAT_BREAKABLETOKEN_H
1970ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
2000895106f9ed602af67984ec4d225a0cdc8c12afAlexander Kornienko#include "Encoding.h"
2170ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko#include "TokenAnnotator.h"
2270ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko#include "WhitespaceManager.h"
2370ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko#include <utility>
2470ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
2570ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienkonamespace clang {
2670ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienkonamespace format {
2770ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
28de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimekstruct FormatStyle;
29de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek
30de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek/// \brief Base class for strategies on how to break tokens.
31de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek///
32de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek/// FIXME: The interface seems set in stone, so we might want to just pull the
33de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek/// strategy into the class, instead of controlling it from the outside.
3470ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienkoclass BreakableToken {
3570ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienkopublic:
362785b9aabcb2c3fd6f7dd8b63d3cd3d4b9bca284Alexander Kornienko  /// \brief Contains starting character index and length of split.
37de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  typedef std::pair<StringRef::size_type, unsigned> Split;
38de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek
3970ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  virtual ~BreakableToken() {}
40de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek
41de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  /// \brief Returns the number of lines in this token in the original code.
4270ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  virtual unsigned getLineCount() const = 0;
43de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek
442785b9aabcb2c3fd6f7dd8b63d3cd3d4b9bca284Alexander Kornienko  /// \brief Returns the number of columns required to format the piece of line
452785b9aabcb2c3fd6f7dd8b63d3cd3d4b9bca284Alexander Kornienko  /// at \p LineIndex, from byte offset \p Offset with length \p Length.
46de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  ///
472785b9aabcb2c3fd6f7dd8b63d3cd3d4b9bca284Alexander Kornienko  /// Note that previous breaks are not taken into account. \p Offset is always
482785b9aabcb2c3fd6f7dd8b63d3cd3d4b9bca284Alexander Kornienko  /// specified from the start of the (original) line.
492785b9aabcb2c3fd6f7dd8b63d3cd3d4b9bca284Alexander Kornienko  /// \p Length can be set to StringRef::npos, which means "to the end of line".
502785b9aabcb2c3fd6f7dd8b63d3cd3d4b9bca284Alexander Kornienko  virtual unsigned
512a409b62126d8f0b8f5749d5ed435ad2b394b526Daniel Jasper  getLineLengthAfterSplit(unsigned LineIndex, unsigned Offset,
522a409b62126d8f0b8f5749d5ed435ad2b394b526Daniel Jasper                          StringRef::size_type Length) const = 0;
5370ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
54de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  /// \brief Returns a range (offset, length) at which to break the line at
55de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  /// \p LineIndex, if previously broken at \p TailOffset. If possible, do not
56de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  /// violate \p ColumnLimit.
5770ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  virtual Split getSplit(unsigned LineIndex, unsigned TailOffset,
58919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko                         unsigned ColumnLimit) const = 0;
59de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek
60de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  /// \brief Emits the previously retrieved \p Split via \p Whitespaces.
6170ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko  virtual void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split,
6270ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko                           WhitespaceManager &Whitespaces) = 0;
63de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek
64a7462b8ce22a3f754bf51eeeb01adafc42b32ceaAlexander Kornienko  /// \brief Replaces the whitespace range described by \p Split with a single
65a7462b8ce22a3f754bf51eeeb01adafc42b32ceaAlexander Kornienko  /// space.
66a7462b8ce22a3f754bf51eeeb01adafc42b32ceaAlexander Kornienko  virtual void replaceWhitespace(unsigned LineIndex, unsigned TailOffset,
67a7462b8ce22a3f754bf51eeeb01adafc42b32ceaAlexander Kornienko                                 Split Split,
68a7462b8ce22a3f754bf51eeeb01adafc42b32ceaAlexander Kornienko                                 WhitespaceManager &Whitespaces) = 0;
69a7462b8ce22a3f754bf51eeeb01adafc42b32ceaAlexander Kornienko
70de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  /// \brief Replaces the whitespace between \p LineIndex-1 and \p LineIndex.
71de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  virtual void replaceWhitespaceBefore(unsigned LineIndex,
72de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek                                       WhitespaceManager &Whitespaces) {}
73de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek
74919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienkoprotected:
753d9ffcf3aa0ed84fa297e3c461bb84e48221aa2dAlexander Kornienko  BreakableToken(const FormatToken &Tok, unsigned IndentLevel,
763d9ffcf3aa0ed84fa297e3c461bb84e48221aa2dAlexander Kornienko                 bool InPPDirective, encoding::Encoding Encoding,
773d9ffcf3aa0ed84fa297e3c461bb84e48221aa2dAlexander Kornienko                 const FormatStyle &Style)
783d9ffcf3aa0ed84fa297e3c461bb84e48221aa2dAlexander Kornienko      : Tok(Tok), IndentLevel(IndentLevel), InPPDirective(InPPDirective),
793d9ffcf3aa0ed84fa297e3c461bb84e48221aa2dAlexander Kornienko        Encoding(Encoding), Style(Style) {}
80de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek
81919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko  const FormatToken &Tok;
823d9ffcf3aa0ed84fa297e3c461bb84e48221aa2dAlexander Kornienko  const unsigned IndentLevel;
8316a0ec60507a4eec275a5c3a86d4501b1b7b817bAlexander Kornienko  const bool InPPDirective;
8416a0ec60507a4eec275a5c3a86d4501b1b7b817bAlexander Kornienko  const encoding::Encoding Encoding;
850b62cc30c9aa462184de0435dc083d944a41d67fAlexander Kornienko  const FormatStyle &Style;
8670ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko};
8770ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
88de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek/// \brief Base class for single line tokens that can be broken.
89de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek///
90de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek/// \c getSplit() needs to be implemented by child classes.
91de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimekclass BreakableSingleLineToken : public BreakableToken {
9270ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienkopublic:
93651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  unsigned getLineCount() const override;
94651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  unsigned getLineLengthAfterSplit(unsigned LineIndex, unsigned TailOffset,
95651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                   StringRef::size_type Length) const override;
9670ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
97de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimekprotected:
983d9ffcf3aa0ed84fa297e3c461bb84e48221aa2dAlexander Kornienko  BreakableSingleLineToken(const FormatToken &Tok, unsigned IndentLevel,
993d9ffcf3aa0ed84fa297e3c461bb84e48221aa2dAlexander Kornienko                           unsigned StartColumn, StringRef Prefix,
1003d9ffcf3aa0ed84fa297e3c461bb84e48221aa2dAlexander Kornienko                           StringRef Postfix, bool InPPDirective,
1013d9ffcf3aa0ed84fa297e3c461bb84e48221aa2dAlexander Kornienko                           encoding::Encoding Encoding,
1020b62cc30c9aa462184de0435dc083d944a41d67fAlexander Kornienko                           const FormatStyle &Style);
10370ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
104de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // The column in which the token starts.
105de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  unsigned StartColumn;
106de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // The prefix a line needs after a break in the token.
107de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  StringRef Prefix;
108de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // The postfix a line needs before introducing a break.
109de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  StringRef Postfix;
110de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // The token text excluding the prefix and postfix.
111de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  StringRef Line;
11270ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko};
11370ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
114de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimekclass BreakableStringLiteral : public BreakableSingleLineToken {
11570ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienkopublic:
116de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  /// \brief Creates a breakable token for a single line string literal.
117de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  ///
118de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  /// \p StartColumn specifies the column in which the token will start
119de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  /// after formatting.
1203d9ffcf3aa0ed84fa297e3c461bb84e48221aa2dAlexander Kornienko  BreakableStringLiteral(const FormatToken &Tok, unsigned IndentLevel,
1213d9ffcf3aa0ed84fa297e3c461bb84e48221aa2dAlexander Kornienko                         unsigned StartColumn, StringRef Prefix,
1223d9ffcf3aa0ed84fa297e3c461bb84e48221aa2dAlexander Kornienko                         StringRef Postfix, bool InPPDirective,
1233d9ffcf3aa0ed84fa297e3c461bb84e48221aa2dAlexander Kornienko                         encoding::Encoding Encoding, const FormatStyle &Style);
12470ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
125651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  Split getSplit(unsigned LineIndex, unsigned TailOffset,
126651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                 unsigned ColumnLimit) const override;
127651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split,
128651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                   WhitespaceManager &Whitespaces) override;
129651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void replaceWhitespace(unsigned LineIndex, unsigned TailOffset, Split Split,
130651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                         WhitespaceManager &Whitespaces) override {}
13170ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko};
13270ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
133de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimekclass BreakableLineComment : public BreakableSingleLineToken {
134919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienkopublic:
135de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  /// \brief Creates a breakable token for a line comment.
136de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  ///
137de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  /// \p StartColumn specifies the column in which the comment will start
138de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  /// after formatting.
1393d9ffcf3aa0ed84fa297e3c461bb84e48221aa2dAlexander Kornienko  BreakableLineComment(const FormatToken &Token, unsigned IndentLevel,
1403d9ffcf3aa0ed84fa297e3c461bb84e48221aa2dAlexander Kornienko                       unsigned StartColumn, bool InPPDirective,
1413d9ffcf3aa0ed84fa297e3c461bb84e48221aa2dAlexander Kornienko                       encoding::Encoding Encoding, const FormatStyle &Style);
142919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko
143651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  Split getSplit(unsigned LineIndex, unsigned TailOffset,
144651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                 unsigned ColumnLimit) const override;
145651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split,
146651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                   WhitespaceManager &Whitespaces) override;
147651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void replaceWhitespace(unsigned LineIndex, unsigned TailOffset, Split Split,
148651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                         WhitespaceManager &Whitespaces) override;
149651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void replaceWhitespaceBefore(unsigned LineIndex,
150651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                               WhitespaceManager &Whitespaces) override;
1512b2faa53ecd32e823c55430d0889c11ea91b582cAlexander Kornienko
1522b2faa53ecd32e823c55430d0889c11ea91b582cAlexander Kornienkoprivate:
1532b2faa53ecd32e823c55430d0889c11ea91b582cAlexander Kornienko  // The prefix without an additional space if one was added.
1542b2faa53ecd32e823c55430d0889c11ea91b582cAlexander Kornienko  StringRef OriginalPrefix;
155de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek};
156919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko
157de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimekclass BreakableBlockComment : public BreakableToken {
158de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimekpublic:
159de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  /// \brief Creates a breakable token for a block comment.
160de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  ///
161de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  /// \p StartColumn specifies the column in which the comment will start
162de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  /// after formatting, while \p OriginalStartColumn specifies in which
163de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  /// column the comment started before formatting.
164de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  /// If the comment starts a line after formatting, set \p FirstInLine to true.
1653d9ffcf3aa0ed84fa297e3c461bb84e48221aa2dAlexander Kornienko  BreakableBlockComment(const FormatToken &Token, unsigned IndentLevel,
1663d9ffcf3aa0ed84fa297e3c461bb84e48221aa2dAlexander Kornienko                        unsigned StartColumn, unsigned OriginaStartColumn,
1673d9ffcf3aa0ed84fa297e3c461bb84e48221aa2dAlexander Kornienko                        bool FirstInLine, bool InPPDirective,
1683d9ffcf3aa0ed84fa297e3c461bb84e48221aa2dAlexander Kornienko                        encoding::Encoding Encoding, const FormatStyle &Style);
169de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek
170651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  unsigned getLineCount() const override;
171651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  unsigned getLineLengthAfterSplit(unsigned LineIndex, unsigned TailOffset,
172651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                   StringRef::size_type Length) const override;
173651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  Split getSplit(unsigned LineIndex, unsigned TailOffset,
174651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                 unsigned ColumnLimit) const override;
175651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split,
176651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                   WhitespaceManager &Whitespaces) override;
177651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void replaceWhitespace(unsigned LineIndex, unsigned TailOffset, Split Split,
178651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                         WhitespaceManager &Whitespaces) override;
179651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void replaceWhitespaceBefore(unsigned LineIndex,
180651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                               WhitespaceManager &Whitespaces) override;
181919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko
182919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienkoprivate:
183de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // Rearranges the whitespace between Lines[LineIndex-1] and Lines[LineIndex],
184de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // so that all whitespace between the lines is accounted to Lines[LineIndex]
185de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // as leading whitespace:
186de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // - Lines[LineIndex] points to the text after that whitespace
187de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // - Lines[LineIndex-1] shrinks by its trailing whitespace
188de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // - LeadingWhitespace[LineIndex] is updated with the complete whitespace
189de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  //   between the end of the text of Lines[LineIndex-1] and Lines[LineIndex]
190de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  //
191de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // Sets StartOfLineColumn to the intended column in which the text at
192de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // Lines[LineIndex] starts (note that the decoration, if present, is not
193de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // considered part of the text).
1940b62cc30c9aa462184de0435dc083d944a41d67fAlexander Kornienko  void adjustWhitespace(unsigned LineIndex, int IndentDelta);
195de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek
196de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // Returns the column at which the text in line LineIndex starts, when broken
197de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // at TailOffset. Note that the decoration (if present) is not considered part
198de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // of the text.
199de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  unsigned getContentStartColumn(unsigned LineIndex, unsigned TailOffset) const;
200de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek
201de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // Contains the text of the lines of the block comment, excluding the leading
202de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // /* in the first line and trailing */ in the last line, and excluding all
203de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // trailing whitespace between the lines. Note that the decoration (if
204de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // present) is also not considered part of the text.
205de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  SmallVector<StringRef, 16> Lines;
206919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko
207de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // LeadingWhitespace[i] is the number of characters regarded as whitespace in
208de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // front of Lines[i]. Note that this can include "* " sequences, which we
209de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // regard as whitespace when all lines have a "*" prefix.
210de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  SmallVector<unsigned, 16> LeadingWhitespace;
211de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek
212de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // StartOfLineColumn[i] is the target column at which Line[i] should be.
213de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // Note that this excludes a leading "* " or "*" in case all lines have
214de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // a "*" prefix.
2156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  SmallVector<int, 16> StartOfLineColumn;
216de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek
217de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // The column at which the text of a broken line should start.
218de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // Note that an optional decoration would go before that column.
219de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // IndentAtLineBreak is a uniform position for all lines in a block comment,
220de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // regardless of their relative position.
221de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // FIXME: Revisit the decision to do this; the main reason was to support
222de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // patterns like
223de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // /**************//**
224de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  //  * Comment
225de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // We could also support such patterns by special casing the first line
226de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // instead.
227de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  unsigned IndentAtLineBreak;
228919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko
2291659dedac63858de50ee60175a88c42ff974e61bAlexander Kornienko  // This is to distinguish between the case when the last line was empty and
2301659dedac63858de50ee60175a88c42ff974e61bAlexander Kornienko  // the case when it started with a decoration ("*" or "* ").
2311659dedac63858de50ee60175a88c42ff974e61bAlexander Kornienko  bool LastLineNeedsDecoration;
2321659dedac63858de50ee60175a88c42ff974e61bAlexander Kornienko
233de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  // Either "* " if all lines begin with a "*", or empty.
234de008c0f3bf66103185fc9f7f49995fa431451a6Manuel Klimek  StringRef Decoration;
235919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko};
236919398bb40d5d643f38b6595f5e8eac641e89d50Alexander Kornienko
23770ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko} // namespace format
23870ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko} // namespace clang
23970ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko
24070ce7881fc30a39b795b2873f008e7eca72ba669Alexander Kornienko#endif // LLVM_CLANG_FORMAT_BREAKABLETOKEN_H
241