blob: 20a2af50121cbff14cfbc640970b8c64352b32f0 [file] [log] [blame]
Daniel Jasperf7935112012-12-03 18:12:45 +00001//===--- Format.cpp - 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 This file implements functions declared in Format.h. This will be
12/// split into separate files as we go.
13///
Daniel Jasperf7935112012-12-03 18:12:45 +000014//===----------------------------------------------------------------------===//
15
Manuel Klimek24998102013-01-16 14:55:28 +000016#define DEBUG_TYPE "format-formatter"
17
Daniel Jasperde0328a2013-08-16 11:20:30 +000018#include "ContinuationIndenter.h"
Daniel Jasper7a6d09b2013-01-29 21:01:14 +000019#include "TokenAnnotator.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000020#include "UnwrappedLineParser.h"
Alexander Kornienkocb45bc12013-04-15 14:28:00 +000021#include "WhitespaceManager.h"
Daniel Jasperec04c0d2013-05-16 10:40:07 +000022#include "clang/Basic/Diagnostic.h"
Chandler Carruth44eb4f62013-01-02 10:28:36 +000023#include "clang/Basic/SourceManager.h"
Manuel Klimek24998102013-01-16 14:55:28 +000024#include "clang/Format/Format.h"
Daniel Jasperf7935112012-12-03 18:12:45 +000025#include "clang/Lex/Lexer.h"
Alexander Kornienkoffd6d042013-03-27 11:52:18 +000026#include "llvm/ADT/STLExtras.h"
Manuel Klimek2ef908e2013-02-13 10:46:36 +000027#include "llvm/Support/Allocator.h"
Manuel Klimek24998102013-01-16 14:55:28 +000028#include "llvm/Support/Debug.h"
Alexander Kornienkod6538332013-05-07 15:32:14 +000029#include "llvm/Support/YAMLTraits.h"
Manuel Klimek2ef908e2013-02-13 10:46:36 +000030#include <queue>
Daniel Jasper8b529712012-12-04 13:02:32 +000031#include <string>
32
Alexander Kornienkod6538332013-05-07 15:32:14 +000033namespace llvm {
34namespace yaml {
35template <>
36struct ScalarEnumerationTraits<clang::format::FormatStyle::LanguageStandard> {
Manuel Klimeka8eb9142013-05-13 12:51:40 +000037 static void enumeration(IO &IO,
38 clang::format::FormatStyle::LanguageStandard &Value) {
39 IO.enumCase(Value, "C++03", clang::format::FormatStyle::LS_Cpp03);
40 IO.enumCase(Value, "C++11", clang::format::FormatStyle::LS_Cpp11);
41 IO.enumCase(Value, "Auto", clang::format::FormatStyle::LS_Auto);
42 }
43};
44
Daniel Jasper12f9d8e2013-05-14 09:30:02 +000045template <>
Manuel Klimeka8eb9142013-05-13 12:51:40 +000046struct ScalarEnumerationTraits<clang::format::FormatStyle::BraceBreakingStyle> {
47 static void
48 enumeration(IO &IO, clang::format::FormatStyle::BraceBreakingStyle &Value) {
49 IO.enumCase(Value, "Attach", clang::format::FormatStyle::BS_Attach);
50 IO.enumCase(Value, "Linux", clang::format::FormatStyle::BS_Linux);
51 IO.enumCase(Value, "Stroustrup", clang::format::FormatStyle::BS_Stroustrup);
Manuel Klimekd3ed59a2013-08-02 21:31:59 +000052 IO.enumCase(Value, "Allman", clang::format::FormatStyle::BS_Allman);
Alexander Kornienkod6538332013-05-07 15:32:14 +000053 }
54};
55
Daniel Jasper65ee3472013-07-31 23:16:02 +000056template <>
57struct ScalarEnumerationTraits<
58 clang::format::FormatStyle::NamespaceIndentationKind> {
59 static void
60 enumeration(IO &IO,
61 clang::format::FormatStyle::NamespaceIndentationKind &Value) {
62 IO.enumCase(Value, "None", clang::format::FormatStyle::NI_None);
63 IO.enumCase(Value, "Inner", clang::format::FormatStyle::NI_Inner);
64 IO.enumCase(Value, "All", clang::format::FormatStyle::NI_All);
65 }
66};
67
Alexander Kornienkod6538332013-05-07 15:32:14 +000068template <> struct MappingTraits<clang::format::FormatStyle> {
69 static void mapping(llvm::yaml::IO &IO, clang::format::FormatStyle &Style) {
Alexander Kornienko49149672013-05-10 11:56:10 +000070 if (IO.outputting()) {
71 StringRef StylesArray[] = { "LLVM", "Google", "Chromium", "Mozilla" };
72 ArrayRef<StringRef> Styles(StylesArray);
73 for (size_t i = 0, e = Styles.size(); i < e; ++i) {
74 StringRef StyleName(Styles[i]);
Alexander Kornienko006b5c82013-05-19 00:53:30 +000075 clang::format::FormatStyle PredefinedStyle;
76 if (clang::format::getPredefinedStyle(StyleName, &PredefinedStyle) &&
77 Style == PredefinedStyle) {
Alexander Kornienko49149672013-05-10 11:56:10 +000078 IO.mapOptional("# BasedOnStyle", StyleName);
79 break;
80 }
81 }
82 } else {
Alexander Kornienkod6538332013-05-07 15:32:14 +000083 StringRef BasedOnStyle;
84 IO.mapOptional("BasedOnStyle", BasedOnStyle);
Alexander Kornienkod6538332013-05-07 15:32:14 +000085 if (!BasedOnStyle.empty())
Alexander Kornienko006b5c82013-05-19 00:53:30 +000086 if (!clang::format::getPredefinedStyle(BasedOnStyle, &Style)) {
87 IO.setError(Twine("Unknown value for BasedOnStyle: ", BasedOnStyle));
88 return;
89 }
Alexander Kornienkod6538332013-05-07 15:32:14 +000090 }
91
92 IO.mapOptional("AccessModifierOffset", Style.AccessModifierOffset);
Daniel Jaspercdaffa42013-08-13 10:58:30 +000093 IO.mapOptional("ConstructorInitializerIndentWidth",
94 Style.ConstructorInitializerIndentWidth);
Alexander Kornienkod6538332013-05-07 15:32:14 +000095 IO.mapOptional("AlignEscapedNewlinesLeft", Style.AlignEscapedNewlinesLeft);
Daniel Jasper552f4a72013-07-31 23:55:15 +000096 IO.mapOptional("AlignTrailingComments", Style.AlignTrailingComments);
Alexander Kornienkod6538332013-05-07 15:32:14 +000097 IO.mapOptional("AllowAllParametersOfDeclarationOnNextLine",
98 Style.AllowAllParametersOfDeclarationOnNextLine);
99 IO.mapOptional("AllowShortIfStatementsOnASingleLine",
100 Style.AllowShortIfStatementsOnASingleLine);
Daniel Jasper3a685df2013-05-16 12:12:21 +0000101 IO.mapOptional("AllowShortLoopsOnASingleLine",
102 Style.AllowShortLoopsOnASingleLine);
Daniel Jasper61e6bbf2013-05-29 12:07:31 +0000103 IO.mapOptional("AlwaysBreakTemplateDeclarations",
104 Style.AlwaysBreakTemplateDeclarations);
Alexander Kornienko58611712013-07-04 12:02:44 +0000105 IO.mapOptional("AlwaysBreakBeforeMultilineStrings",
106 Style.AlwaysBreakBeforeMultilineStrings);
Daniel Jaspere33d4af2013-07-26 16:56:36 +0000107 IO.mapOptional("BreakBeforeBinaryOperators",
108 Style.BreakBeforeBinaryOperators);
109 IO.mapOptional("BreakConstructorInitializersBeforeComma",
110 Style.BreakConstructorInitializersBeforeComma);
Alexander Kornienkod6538332013-05-07 15:32:14 +0000111 IO.mapOptional("BinPackParameters", Style.BinPackParameters);
112 IO.mapOptional("ColumnLimit", Style.ColumnLimit);
113 IO.mapOptional("ConstructorInitializerAllOnOneLineOrOnePerLine",
114 Style.ConstructorInitializerAllOnOneLineOrOnePerLine);
115 IO.mapOptional("DerivePointerBinding", Style.DerivePointerBinding);
Daniel Jasperb10cbc42013-07-10 14:02:49 +0000116 IO.mapOptional("ExperimentalAutoDetectBinPacking",
117 Style.ExperimentalAutoDetectBinPacking);
Alexander Kornienkod6538332013-05-07 15:32:14 +0000118 IO.mapOptional("IndentCaseLabels", Style.IndentCaseLabels);
119 IO.mapOptional("MaxEmptyLinesToKeep", Style.MaxEmptyLinesToKeep);
Daniel Jasper65ee3472013-07-31 23:16:02 +0000120 IO.mapOptional("NamespaceIndentation", Style.NamespaceIndentation);
Alexander Kornienkod6538332013-05-07 15:32:14 +0000121 IO.mapOptional("ObjCSpaceBeforeProtocolList",
122 Style.ObjCSpaceBeforeProtocolList);
Alexander Kornienkodd7ece52013-06-07 16:02:52 +0000123 IO.mapOptional("PenaltyBreakComment", Style.PenaltyBreakComment);
124 IO.mapOptional("PenaltyBreakString", Style.PenaltyBreakString);
Daniel Jasper4e9678f2013-07-11 20:41:21 +0000125 IO.mapOptional("PenaltyBreakFirstLessLess",
126 Style.PenaltyBreakFirstLessLess);
Alexander Kornienkod6538332013-05-07 15:32:14 +0000127 IO.mapOptional("PenaltyExcessCharacter", Style.PenaltyExcessCharacter);
128 IO.mapOptional("PenaltyReturnTypeOnItsOwnLine",
129 Style.PenaltyReturnTypeOnItsOwnLine);
130 IO.mapOptional("PointerBindsToType", Style.PointerBindsToType);
131 IO.mapOptional("SpacesBeforeTrailingComments",
132 Style.SpacesBeforeTrailingComments);
Daniel Jasper6ab54682013-07-16 18:22:10 +0000133 IO.mapOptional("Cpp11BracedListStyle", Style.Cpp11BracedListStyle);
Alexander Kornienkod6538332013-05-07 15:32:14 +0000134 IO.mapOptional("Standard", Style.Standard);
Manuel Klimek13b97d82013-05-13 08:42:42 +0000135 IO.mapOptional("IndentWidth", Style.IndentWidth);
Manuel Klimekb9eae4c2013-05-13 09:22:11 +0000136 IO.mapOptional("UseTab", Style.UseTab);
Manuel Klimeka8eb9142013-05-13 12:51:40 +0000137 IO.mapOptional("BreakBeforeBraces", Style.BreakBeforeBraces);
Manuel Klimek836c2862013-06-21 17:25:42 +0000138 IO.mapOptional("IndentFunctionDeclarationAfterType",
139 Style.IndentFunctionDeclarationAfterType);
Alexander Kornienkod6538332013-05-07 15:32:14 +0000140 }
141};
142}
143}
144
Daniel Jasperf7935112012-12-03 18:12:45 +0000145namespace clang {
146namespace format {
147
Daniel Jasper4e9678f2013-07-11 20:41:21 +0000148void setDefaultPenalties(FormatStyle &Style) {
149 Style.PenaltyBreakComment = 45;
Daniel Jasperfa21c072013-07-15 14:33:14 +0000150 Style.PenaltyBreakFirstLessLess = 120;
Daniel Jasper4e9678f2013-07-11 20:41:21 +0000151 Style.PenaltyBreakString = 1000;
152 Style.PenaltyExcessCharacter = 1000000;
153}
154
Daniel Jasperf7935112012-12-03 18:12:45 +0000155FormatStyle getLLVMStyle() {
156 FormatStyle LLVMStyle;
Daniel Jasperf7935112012-12-03 18:12:45 +0000157 LLVMStyle.AccessModifierOffset = -2;
Alexander Kornienkoc8602662013-05-06 14:11:27 +0000158 LLVMStyle.AlignEscapedNewlinesLeft = false;
Daniel Jasper552f4a72013-07-31 23:55:15 +0000159 LLVMStyle.AlignTrailingComments = true;
Daniel Jasperf7db4332013-01-29 16:03:49 +0000160 LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true;
Daniel Jasper1b750ed2013-01-14 16:24:39 +0000161 LLVMStyle.AllowShortIfStatementsOnASingleLine = false;
Daniel Jasper3a685df2013-05-16 12:12:21 +0000162 LLVMStyle.AllowShortLoopsOnASingleLine = false;
Alexander Kornienko58611712013-07-04 12:02:44 +0000163 LLVMStyle.AlwaysBreakBeforeMultilineStrings = false;
Daniel Jaspere33d4af2013-07-26 16:56:36 +0000164 LLVMStyle.AlwaysBreakTemplateDeclarations = false;
Alexander Kornienkoc8602662013-05-06 14:11:27 +0000165 LLVMStyle.BinPackParameters = true;
Daniel Jaspere33d4af2013-07-26 16:56:36 +0000166 LLVMStyle.BreakBeforeBinaryOperators = false;
167 LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach;
168 LLVMStyle.BreakConstructorInitializersBeforeComma = false;
Alexander Kornienkoc8602662013-05-06 14:11:27 +0000169 LLVMStyle.ColumnLimit = 80;
170 LLVMStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = false;
Daniel Jaspercdaffa42013-08-13 10:58:30 +0000171 LLVMStyle.ConstructorInitializerIndentWidth = 4;
Daniel Jaspere33d4af2013-07-26 16:56:36 +0000172 LLVMStyle.Cpp11BracedListStyle = false;
Alexander Kornienkoc8602662013-05-06 14:11:27 +0000173 LLVMStyle.DerivePointerBinding = false;
Daniel Jasperb10cbc42013-07-10 14:02:49 +0000174 LLVMStyle.ExperimentalAutoDetectBinPacking = false;
Alexander Kornienkoc8602662013-05-06 14:11:27 +0000175 LLVMStyle.IndentCaseLabels = false;
Daniel Jaspere33d4af2013-07-26 16:56:36 +0000176 LLVMStyle.IndentFunctionDeclarationAfterType = false;
177 LLVMStyle.IndentWidth = 2;
Alexander Kornienkoc8602662013-05-06 14:11:27 +0000178 LLVMStyle.MaxEmptyLinesToKeep = 1;
Daniel Jasper65ee3472013-07-31 23:16:02 +0000179 LLVMStyle.NamespaceIndentation = FormatStyle::NI_None;
Nico Webera6087752013-01-10 20:12:55 +0000180 LLVMStyle.ObjCSpaceBeforeProtocolList = true;
Alexander Kornienkoc8602662013-05-06 14:11:27 +0000181 LLVMStyle.PointerBindsToType = false;
182 LLVMStyle.SpacesBeforeTrailingComments = 1;
183 LLVMStyle.Standard = FormatStyle::LS_Cpp03;
Manuel Klimekb9eae4c2013-05-13 09:22:11 +0000184 LLVMStyle.UseTab = false;
Daniel Jasper4e9678f2013-07-11 20:41:21 +0000185
186 setDefaultPenalties(LLVMStyle);
187 LLVMStyle.PenaltyReturnTypeOnItsOwnLine = 60;
188
Daniel Jasperf7935112012-12-03 18:12:45 +0000189 return LLVMStyle;
190}
191
192FormatStyle getGoogleStyle() {
193 FormatStyle GoogleStyle;
Daniel Jasperf7935112012-12-03 18:12:45 +0000194 GoogleStyle.AccessModifierOffset = -1;
Alexander Kornienkoc8602662013-05-06 14:11:27 +0000195 GoogleStyle.AlignEscapedNewlinesLeft = true;
Daniel Jasper552f4a72013-07-31 23:55:15 +0000196 GoogleStyle.AlignTrailingComments = true;
Daniel Jasperf7db4332013-01-29 16:03:49 +0000197 GoogleStyle.AllowAllParametersOfDeclarationOnNextLine = true;
Daniel Jasper085a2ed2013-04-24 13:46:00 +0000198 GoogleStyle.AllowShortIfStatementsOnASingleLine = true;
Daniel Jasper5bd0b9e2013-05-23 18:05:18 +0000199 GoogleStyle.AllowShortLoopsOnASingleLine = true;
Alexander Kornienko58611712013-07-04 12:02:44 +0000200 GoogleStyle.AlwaysBreakBeforeMultilineStrings = true;
Daniel Jaspere33d4af2013-07-26 16:56:36 +0000201 GoogleStyle.AlwaysBreakTemplateDeclarations = true;
Alexander Kornienkoc8602662013-05-06 14:11:27 +0000202 GoogleStyle.BinPackParameters = true;
Daniel Jaspere33d4af2013-07-26 16:56:36 +0000203 GoogleStyle.BreakBeforeBinaryOperators = false;
204 GoogleStyle.BreakBeforeBraces = FormatStyle::BS_Attach;
205 GoogleStyle.BreakConstructorInitializersBeforeComma = false;
Alexander Kornienkoc8602662013-05-06 14:11:27 +0000206 GoogleStyle.ColumnLimit = 80;
207 GoogleStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = true;
Daniel Jaspercdaffa42013-08-13 10:58:30 +0000208 GoogleStyle.ConstructorInitializerIndentWidth = 4;
Daniel Jaspere33d4af2013-07-26 16:56:36 +0000209 GoogleStyle.Cpp11BracedListStyle = true;
Alexander Kornienkoc8602662013-05-06 14:11:27 +0000210 GoogleStyle.DerivePointerBinding = true;
Daniel Jasperb10cbc42013-07-10 14:02:49 +0000211 GoogleStyle.ExperimentalAutoDetectBinPacking = false;
Alexander Kornienkoc8602662013-05-06 14:11:27 +0000212 GoogleStyle.IndentCaseLabels = true;
Daniel Jaspere33d4af2013-07-26 16:56:36 +0000213 GoogleStyle.IndentFunctionDeclarationAfterType = true;
214 GoogleStyle.IndentWidth = 2;
Alexander Kornienkoc8602662013-05-06 14:11:27 +0000215 GoogleStyle.MaxEmptyLinesToKeep = 1;
Daniel Jasper65ee3472013-07-31 23:16:02 +0000216 GoogleStyle.NamespaceIndentation = FormatStyle::NI_None;
Nico Webera6087752013-01-10 20:12:55 +0000217 GoogleStyle.ObjCSpaceBeforeProtocolList = false;
Alexander Kornienkoc8602662013-05-06 14:11:27 +0000218 GoogleStyle.PointerBindsToType = true;
219 GoogleStyle.SpacesBeforeTrailingComments = 2;
220 GoogleStyle.Standard = FormatStyle::LS_Auto;
Manuel Klimekb9eae4c2013-05-13 09:22:11 +0000221 GoogleStyle.UseTab = false;
Daniel Jasper4e9678f2013-07-11 20:41:21 +0000222
223 setDefaultPenalties(GoogleStyle);
224 GoogleStyle.PenaltyReturnTypeOnItsOwnLine = 200;
225
Daniel Jasperf7935112012-12-03 18:12:45 +0000226 return GoogleStyle;
227}
228
Daniel Jasper1b750ed2013-01-14 16:24:39 +0000229FormatStyle getChromiumStyle() {
230 FormatStyle ChromiumStyle = getGoogleStyle();
Daniel Jasperf7db4332013-01-29 16:03:49 +0000231 ChromiumStyle.AllowAllParametersOfDeclarationOnNextLine = false;
Daniel Jasper085a2ed2013-04-24 13:46:00 +0000232 ChromiumStyle.AllowShortIfStatementsOnASingleLine = false;
Daniel Jasper3a685df2013-05-16 12:12:21 +0000233 ChromiumStyle.AllowShortLoopsOnASingleLine = false;
Daniel Jasper2cf17bf2013-02-27 09:47:53 +0000234 ChromiumStyle.BinPackParameters = false;
Daniel Jasper7fce3ab2013-02-06 14:22:40 +0000235 ChromiumStyle.DerivePointerBinding = false;
Daniel Jaspere33d4af2013-07-26 16:56:36 +0000236 ChromiumStyle.Standard = FormatStyle::LS_Cpp03;
Daniel Jasper1b750ed2013-01-14 16:24:39 +0000237 return ChromiumStyle;
238}
239
Alexander Kornienkoc8602662013-05-06 14:11:27 +0000240FormatStyle getMozillaStyle() {
241 FormatStyle MozillaStyle = getLLVMStyle();
242 MozillaStyle.AllowAllParametersOfDeclarationOnNextLine = false;
243 MozillaStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = true;
244 MozillaStyle.DerivePointerBinding = true;
245 MozillaStyle.IndentCaseLabels = true;
246 MozillaStyle.ObjCSpaceBeforeProtocolList = false;
247 MozillaStyle.PenaltyReturnTypeOnItsOwnLine = 200;
248 MozillaStyle.PointerBindsToType = true;
249 return MozillaStyle;
250}
251
Daniel Jasperffefb3d2013-07-24 13:10:59 +0000252FormatStyle getWebKitStyle() {
253 FormatStyle Style = getLLVMStyle();
Daniel Jasper65ee3472013-07-31 23:16:02 +0000254 Style.AccessModifierOffset = -4;
Daniel Jasper552f4a72013-07-31 23:55:15 +0000255 Style.AlignTrailingComments = false;
Daniel Jaspere33d4af2013-07-26 16:56:36 +0000256 Style.BreakBeforeBinaryOperators = true;
Daniel Jasper65ee3472013-07-31 23:16:02 +0000257 Style.BreakBeforeBraces = FormatStyle::BS_Stroustrup;
Daniel Jaspere33d4af2013-07-26 16:56:36 +0000258 Style.BreakConstructorInitializersBeforeComma = true;
Daniel Jasper65ee3472013-07-31 23:16:02 +0000259 Style.ColumnLimit = 0;
Daniel Jaspere33d4af2013-07-26 16:56:36 +0000260 Style.IndentWidth = 4;
Daniel Jasper65ee3472013-07-31 23:16:02 +0000261 Style.NamespaceIndentation = FormatStyle::NI_Inner;
Daniel Jasperffefb3d2013-07-24 13:10:59 +0000262 Style.PointerBindsToType = true;
263 return Style;
264}
265
Alexander Kornienko006b5c82013-05-19 00:53:30 +0000266bool getPredefinedStyle(StringRef Name, FormatStyle *Style) {
Alexander Kornienkod6538332013-05-07 15:32:14 +0000267 if (Name.equals_lower("llvm"))
Alexander Kornienko006b5c82013-05-19 00:53:30 +0000268 *Style = getLLVMStyle();
269 else if (Name.equals_lower("chromium"))
270 *Style = getChromiumStyle();
271 else if (Name.equals_lower("mozilla"))
272 *Style = getMozillaStyle();
273 else if (Name.equals_lower("google"))
274 *Style = getGoogleStyle();
Daniel Jasperffefb3d2013-07-24 13:10:59 +0000275 else if (Name.equals_lower("webkit"))
276 *Style = getWebKitStyle();
Alexander Kornienko006b5c82013-05-19 00:53:30 +0000277 else
278 return false;
Alexander Kornienkod6538332013-05-07 15:32:14 +0000279
Alexander Kornienko006b5c82013-05-19 00:53:30 +0000280 return true;
Alexander Kornienkod6538332013-05-07 15:32:14 +0000281}
282
283llvm::error_code parseConfiguration(StringRef Text, FormatStyle *Style) {
Alexander Kornienko06e00332013-05-20 15:18:01 +0000284 if (Text.trim().empty())
285 return llvm::make_error_code(llvm::errc::invalid_argument);
Alexander Kornienkod6538332013-05-07 15:32:14 +0000286 llvm::yaml::Input Input(Text);
287 Input >> *Style;
288 return Input.error();
289}
290
291std::string configurationAsText(const FormatStyle &Style) {
292 std::string Text;
293 llvm::raw_string_ostream Stream(Text);
294 llvm::yaml::Output Output(Stream);
295 // We use the same mapping method for input and output, so we need a non-const
296 // reference here.
297 FormatStyle NonConstStyle = Style;
298 Output << NonConstStyle;
Alexander Kornienko9a38ec22013-05-13 12:56:35 +0000299 return Stream.str();
Alexander Kornienkod6538332013-05-07 15:32:14 +0000300}
301
Craig Topperaf35e852013-06-30 22:29:28 +0000302namespace {
303
Daniel Jasperde0328a2013-08-16 11:20:30 +0000304class NoColumnLimitFormatter {
305public:
306 NoColumnLimitFormatter(ContinuationIndenter *Indenter)
307 : Indenter(Indenter) {}
308
309 /// \brief Formats the line starting at \p State, simply keeping all of the
310 /// input's line breaking decisions.
311 void format() {
312 LineState State = Indenter->getInitialState();
313 while (State.NextToken != NULL) {
314 bool Newline =
315 Indenter->mustBreak(State) ||
316 (Indenter->canBreak(State) && State.NextToken->NewlinesBefore > 0);
317 Indenter->addTokenToState(State, Newline, /*DryRun=*/false);
318 }
319 }
320private:
321 ContinuationIndenter *Indenter;
322};
323
Daniel Jasperf7935112012-12-03 18:12:45 +0000324class UnwrappedLineFormatter {
325public:
Daniel Jasperde0328a2013-08-16 11:20:30 +0000326 UnwrappedLineFormatter(ContinuationIndenter *Indenter,
327 const FormatStyle &Style, const AnnotatedLine &Line)
328 : Indenter(Indenter), Style(Style), Line(Line), Count(0) {}
Daniel Jasperf7935112012-12-03 18:12:45 +0000329
Manuel Klimek1abf7892013-01-04 23:34:14 +0000330 /// \brief Formats an \c UnwrappedLine.
Daniel Jasperde0328a2013-08-16 11:20:30 +0000331 void format() {
332 LineState State = Indenter->getInitialState();
Daniel Jasper4b866272013-02-01 11:00:45 +0000333
Daniel Jasperacc33662013-02-08 08:22:00 +0000334 // If the ObjC method declaration does not fit on a line, we should format
335 // it with one arg per line.
336 if (Line.Type == LT_ObjCMethodDecl)
337 State.Stack.back().BreakBeforeParameter = true;
338
Daniel Jasper4b866272013-02-01 11:00:45 +0000339 // Find best solution in solution space.
Manuel Klimek4fe43002013-05-22 12:51:29 +0000340 analyzeSolutionSpace(State);
Daniel Jasperf7935112012-12-03 18:12:45 +0000341 }
342
343private:
Manuel Klimek2ef908e2013-02-13 10:46:36 +0000344 /// \brief An edge in the solution space from \c Previous->State to \c State,
345 /// inserting a newline dependent on the \c NewLine.
346 struct StateNode {
347 StateNode(const LineState &State, bool NewLine, StateNode *Previous)
Daniel Jasper12ef4e52013-02-21 21:33:55 +0000348 : State(State), NewLine(NewLine), Previous(Previous) {}
Manuel Klimek2ef908e2013-02-13 10:46:36 +0000349 LineState State;
350 bool NewLine;
351 StateNode *Previous;
352 };
Daniel Jasper4b866272013-02-01 11:00:45 +0000353
Manuel Klimek2ef908e2013-02-13 10:46:36 +0000354 /// \brief A pair of <penalty, count> that is used to prioritize the BFS on.
355 ///
356 /// In case of equal penalties, we want to prefer states that were inserted
357 /// first. During state generation we make sure that we insert states first
358 /// that break the line as late as possible.
359 typedef std::pair<unsigned, unsigned> OrderedPenalty;
360
361 /// \brief An item in the prioritized BFS search queue. The \c StateNode's
362 /// \c State has the given \c OrderedPenalty.
363 typedef std::pair<OrderedPenalty, StateNode *> QueueItem;
364
365 /// \brief The BFS queue type.
366 typedef std::priority_queue<QueueItem, std::vector<QueueItem>,
367 std::greater<QueueItem> > QueueType;
Daniel Jasper4b866272013-02-01 11:00:45 +0000368
369 /// \brief Analyze the entire solution space starting from \p InitialState.
Daniel Jasperf7935112012-12-03 18:12:45 +0000370 ///
Daniel Jasper4b866272013-02-01 11:00:45 +0000371 /// This implements a variant of Dijkstra's algorithm on the graph that spans
372 /// the solution space (\c LineStates are the nodes). The algorithm tries to
373 /// find the shortest path (the one with lowest penalty) from \p InitialState
374 /// to a state where all tokens are placed.
Manuel Klimek4fe43002013-05-22 12:51:29 +0000375 void analyzeSolutionSpace(LineState &InitialState) {
Manuel Klimek2ef908e2013-02-13 10:46:36 +0000376 std::set<LineState> Seen;
377
Daniel Jasper4b866272013-02-01 11:00:45 +0000378 // Insert start element into queue.
Daniel Jasper687af3b2013-02-14 14:26:07 +0000379 StateNode *Node =
Manuel Klimek2ef908e2013-02-13 10:46:36 +0000380 new (Allocator.Allocate()) StateNode(InitialState, false, NULL);
381 Queue.push(QueueItem(OrderedPenalty(0, Count), Node));
382 ++Count;
Daniel Jasper4b866272013-02-01 11:00:45 +0000383
384 // While not empty, take first element and follow edges.
385 while (!Queue.empty()) {
Manuel Klimek2ef908e2013-02-13 10:46:36 +0000386 unsigned Penalty = Queue.top().first.first;
Daniel Jasper687af3b2013-02-14 14:26:07 +0000387 StateNode *Node = Queue.top().second;
Manuel Klimek2ef908e2013-02-13 10:46:36 +0000388 if (Node->State.NextToken == NULL) {
Alexander Kornienko49149672013-05-10 11:56:10 +0000389 DEBUG(llvm::dbgs() << "\n---\nPenalty for line: " << Penalty << "\n");
Daniel Jasper4b866272013-02-01 11:00:45 +0000390 break;
Daniel Jasper3a9370c2013-02-04 07:21:18 +0000391 }
Manuel Klimek2ef908e2013-02-13 10:46:36 +0000392 Queue.pop();
Daniel Jasper4b866272013-02-01 11:00:45 +0000393
Daniel Jasperf8114cf2013-05-22 05:27:42 +0000394 // Cut off the analysis of certain solutions if the analysis gets too
395 // complex. See description of IgnoreStackForComparison.
396 if (Count > 10000)
397 Node->State.IgnoreStackForComparison = true;
398
Manuel Klimek2ef908e2013-02-13 10:46:36 +0000399 if (!Seen.insert(Node->State).second)
400 // State already examined with lower penalty.
401 continue;
Daniel Jasper4b866272013-02-01 11:00:45 +0000402
Nico Weber9096fc02013-06-26 00:30:14 +0000403 addNextStateToQueue(Penalty, Node, /*NewLine=*/false);
404 addNextStateToQueue(Penalty, Node, /*NewLine=*/true);
Daniel Jasper4b866272013-02-01 11:00:45 +0000405 }
406
407 if (Queue.empty())
408 // We were unable to find a solution, do nothing.
409 // FIXME: Add diagnostic?
Manuel Klimek4fe43002013-05-22 12:51:29 +0000410 return;
Daniel Jasperf7935112012-12-03 18:12:45 +0000411
Daniel Jasper4b866272013-02-01 11:00:45 +0000412 // Reconstruct the solution.
Manuel Klimek2ef908e2013-02-13 10:46:36 +0000413 reconstructPath(InitialState, Queue.top().second);
Alexander Kornienko49149672013-05-10 11:56:10 +0000414 DEBUG(llvm::dbgs() << "Total number of analyzed states: " << Count << "\n");
415 DEBUG(llvm::dbgs() << "---\n");
Manuel Klimek2ef908e2013-02-13 10:46:36 +0000416 }
417
418 void reconstructPath(LineState &State, StateNode *Current) {
Manuel Klimek4c5c28b2013-05-29 15:10:11 +0000419 std::deque<StateNode *> Path;
420 // We do not need a break before the initial token.
421 while (Current->Previous) {
422 Path.push_front(Current);
423 Current = Current->Previous;
424 }
425 for (std::deque<StateNode *>::iterator I = Path.begin(), E = Path.end();
426 I != E; ++I) {
427 DEBUG({
428 if ((*I)->NewLine) {
429 llvm::dbgs() << "Penalty for splitting before "
430 << (*I)->Previous->State.NextToken->Tok.getName() << ": "
431 << (*I)->Previous->State.NextToken->SplitPenalty << "\n";
432 }
433 });
Daniel Jasperde0328a2013-08-16 11:20:30 +0000434 Indenter->addTokenToState(State, (*I)->NewLine, false);
Manuel Klimek4c5c28b2013-05-29 15:10:11 +0000435 }
Daniel Jasper4b866272013-02-01 11:00:45 +0000436 }
437
Manuel Klimekaf491072013-02-13 10:54:19 +0000438 /// \brief Add the following state to the analysis queue \c Queue.
Daniel Jasper4b866272013-02-01 11:00:45 +0000439 ///
Manuel Klimekaf491072013-02-13 10:54:19 +0000440 /// Assume the current state is \p PreviousNode and has been reached with a
Daniel Jasper4b866272013-02-01 11:00:45 +0000441 /// penalty of \p Penalty. Insert a line break if \p NewLine is \c true.
Manuel Klimekaf491072013-02-13 10:54:19 +0000442 void addNextStateToQueue(unsigned Penalty, StateNode *PreviousNode,
443 bool NewLine) {
Daniel Jasperde0328a2013-08-16 11:20:30 +0000444 if (NewLine && !Indenter->canBreak(PreviousNode->State))
Daniel Jasper4b866272013-02-01 11:00:45 +0000445 return;
Daniel Jasperde0328a2013-08-16 11:20:30 +0000446 if (!NewLine && Indenter->mustBreak(PreviousNode->State))
Daniel Jasper4b866272013-02-01 11:00:45 +0000447 return;
Daniel Jasperee7539a2013-07-08 14:25:23 +0000448 if (NewLine) {
449 if (!PreviousNode->State.Stack.back().ContainsLineBreak)
450 Penalty += 15;
Manuel Klimek2ef908e2013-02-13 10:46:36 +0000451 Penalty += PreviousNode->State.NextToken->SplitPenalty;
Daniel Jasperee7539a2013-07-08 14:25:23 +0000452 }
Manuel Klimek2ef908e2013-02-13 10:46:36 +0000453
454 StateNode *Node = new (Allocator.Allocate())
455 StateNode(PreviousNode->State, NewLine, PreviousNode);
Daniel Jasperde0328a2013-08-16 11:20:30 +0000456 Penalty += Indenter->addTokenToState(Node->State, NewLine, true);
457 if (Node->State.Column > Indenter->getColumnLimit()) {
458 unsigned ExcessCharacters =
459 Node->State.Column - Indenter->getColumnLimit();
Daniel Jasper3a9370c2013-02-04 07:21:18 +0000460 Penalty += Style.PenaltyExcessCharacter * ExcessCharacters;
Daniel Jasper2df93312013-01-09 10:16:05 +0000461 }
Manuel Klimek2ef908e2013-02-13 10:46:36 +0000462
463 Queue.push(QueueItem(OrderedPenalty(Penalty, Count), Node));
464 ++Count;
Daniel Jasper4b866272013-02-01 11:00:45 +0000465 }
Daniel Jasperf7935112012-12-03 18:12:45 +0000466
Daniel Jasperde0328a2013-08-16 11:20:30 +0000467 ContinuationIndenter *Indenter;
Daniel Jasperf7935112012-12-03 18:12:45 +0000468 FormatStyle Style;
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +0000469 const AnnotatedLine &Line;
Manuel Klimekaf491072013-02-13 10:54:19 +0000470
471 llvm::SpecificBumpPtrAllocator<StateNode> Allocator;
472 QueueType Queue;
473 // Increasing count of \c StateNode items we have created. This is used
474 // to create a deterministic order independent of the container.
475 unsigned Count;
Daniel Jasperf7935112012-12-03 18:12:45 +0000476};
477
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000478class FormatTokenLexer {
Alexander Kornienkoe3276842012-12-07 16:15:44 +0000479public:
Alexander Kornienkoffcc0102013-06-05 14:09:10 +0000480 FormatTokenLexer(Lexer &Lex, SourceManager &SourceMgr,
481 encoding::Encoding Encoding)
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000482 : FormatTok(NULL), GreaterStashed(false), TrailingWhitespace(0), Lex(Lex),
Daniel Jasper8b1c6352013-08-01 17:58:23 +0000483 SourceMgr(SourceMgr), IdentTable(getFormattingLangOpts()),
Alexander Kornienkoffcc0102013-06-05 14:09:10 +0000484 Encoding(Encoding) {
Alexander Kornienkoe3276842012-12-07 16:15:44 +0000485 Lex.SetKeepWhitespaceMode(true);
486 }
487
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000488 ArrayRef<FormatToken *> lex() {
489 assert(Tokens.empty());
490 do {
491 Tokens.push_back(getNextToken());
492 } while (Tokens.back()->Tok.isNot(tok::eof));
493 return Tokens;
494 }
495
496 IdentifierTable &getIdentTable() { return IdentTable; }
497
498private:
499 FormatToken *getNextToken() {
Alexander Kornienkoe3276842012-12-07 16:15:44 +0000500 if (GreaterStashed) {
Manuel Klimek591ab5a2013-05-28 13:42:28 +0000501 // Create a synthesized second '>' token.
502 Token Greater = FormatTok->Tok;
503 FormatTok = new (Allocator.Allocate()) FormatToken;
504 FormatTok->Tok = Greater;
Manuel Klimek5c24cca2013-05-23 10:56:37 +0000505 SourceLocation GreaterLocation =
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000506 FormatTok->Tok.getLocation().getLocWithOffset(1);
507 FormatTok->WhitespaceRange =
508 SourceRange(GreaterLocation, GreaterLocation);
Alexander Kornienkoee4ca9b2013-06-07 17:45:07 +0000509 FormatTok->TokenText = ">";
Alexander Kornienkoffcc0102013-06-05 14:09:10 +0000510 FormatTok->CodePointCount = 1;
Alexander Kornienkoe3276842012-12-07 16:15:44 +0000511 GreaterStashed = false;
512 return FormatTok;
513 }
514
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000515 FormatTok = new (Allocator.Allocate()) FormatToken;
Daniel Jasper8369aa52013-07-16 20:28:33 +0000516 readRawToken(*FormatTok);
Manuel Klimek9043c742013-05-27 15:23:34 +0000517 SourceLocation WhitespaceStart =
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000518 FormatTok->Tok.getLocation().getLocWithOffset(-TrailingWhitespace);
Manuel Klimek5c24cca2013-05-23 10:56:37 +0000519 if (SourceMgr.getFileOffset(WhitespaceStart) == 0)
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000520 FormatTok->IsFirst = true;
Alexander Kornienkoe3276842012-12-07 16:15:44 +0000521
522 // Consume and record whitespace until we find a significant token.
Manuel Klimek9043c742013-05-27 15:23:34 +0000523 unsigned WhitespaceLength = TrailingWhitespace;
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000524 while (FormatTok->Tok.is(tok::unknown)) {
Daniel Jasper8369aa52013-07-16 20:28:33 +0000525 unsigned Newlines = FormatTok->TokenText.count('\n');
Daniel Jasper973c9422013-03-04 13:43:19 +0000526 if (Newlines > 0)
Daniel Jasper8369aa52013-07-16 20:28:33 +0000527 FormatTok->LastNewlineOffset =
528 WhitespaceLength + FormatTok->TokenText.rfind('\n') + 1;
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000529 FormatTok->NewlinesBefore += Newlines;
Daniel Jasper8369aa52013-07-16 20:28:33 +0000530 unsigned EscapedNewlines = FormatTok->TokenText.count("\\\n");
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000531 FormatTok->HasUnescapedNewline |= EscapedNewlines != Newlines;
532 WhitespaceLength += FormatTok->Tok.getLength();
Alexander Kornienkoe3276842012-12-07 16:15:44 +0000533
Daniel Jasper8369aa52013-07-16 20:28:33 +0000534 readRawToken(*FormatTok);
Manuel Klimek1abf7892013-01-04 23:34:14 +0000535 }
Manuel Klimekef920692013-01-07 07:56:50 +0000536
Manuel Klimek1abf7892013-01-04 23:34:14 +0000537 // In case the token starts with escaped newlines, we want to
538 // take them into account as whitespace - this pattern is quite frequent
539 // in macro definitions.
540 // FIXME: What do we want to do with other escaped spaces, and escaped
541 // spaces or newlines in the middle of tokens?
542 // FIXME: Add a more explicit test.
Daniel Jasper8369aa52013-07-16 20:28:33 +0000543 while (FormatTok->TokenText.size() > 1 && FormatTok->TokenText[0] == '\\' &&
544 FormatTok->TokenText[1] == '\n') {
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000545 // FIXME: ++FormatTok->NewlinesBefore is missing...
Manuel Klimek5c24cca2013-05-23 10:56:37 +0000546 WhitespaceLength += 2;
Daniel Jasper8369aa52013-07-16 20:28:33 +0000547 FormatTok->TokenText = FormatTok->TokenText.substr(2);
Alexander Kornienkoe3276842012-12-07 16:15:44 +0000548 }
549
Alexander Kornienkoee4ca9b2013-06-07 17:45:07 +0000550 TrailingWhitespace = 0;
551 if (FormatTok->Tok.is(tok::comment)) {
Daniel Jasper8369aa52013-07-16 20:28:33 +0000552 StringRef UntrimmedText = FormatTok->TokenText;
553 FormatTok->TokenText = FormatTok->TokenText.rtrim();
554 TrailingWhitespace = UntrimmedText.size() - FormatTok->TokenText.size();
Alexander Kornienkoee4ca9b2013-06-07 17:45:07 +0000555 } else if (FormatTok->Tok.is(tok::raw_identifier)) {
Daniel Jasper8369aa52013-07-16 20:28:33 +0000556 IdentifierInfo &Info = IdentTable.get(FormatTok->TokenText);
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000557 FormatTok->Tok.setIdentifierInfo(&Info);
558 FormatTok->Tok.setKind(Info.getTokenID());
Alexander Kornienkoee4ca9b2013-06-07 17:45:07 +0000559 } else if (FormatTok->Tok.is(tok::greatergreater)) {
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000560 FormatTok->Tok.setKind(tok::greater);
Daniel Jasper8369aa52013-07-16 20:28:33 +0000561 FormatTok->TokenText = FormatTok->TokenText.substr(0, 1);
Alexander Kornienkoe3276842012-12-07 16:15:44 +0000562 GreaterStashed = true;
563 }
564
Alexander Kornienkoee4ca9b2013-06-07 17:45:07 +0000565 // Now FormatTok is the next non-whitespace token.
Daniel Jasper8369aa52013-07-16 20:28:33 +0000566 FormatTok->CodePointCount =
567 encoding::getCodePointCount(FormatTok->TokenText, Encoding);
Alexander Kornienkoffcc0102013-06-05 14:09:10 +0000568
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000569 FormatTok->WhitespaceRange = SourceRange(
Manuel Klimek5c24cca2013-05-23 10:56:37 +0000570 WhitespaceStart, WhitespaceStart.getLocWithOffset(WhitespaceLength));
Alexander Kornienkoe3276842012-12-07 16:15:44 +0000571 return FormatTok;
572 }
573
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000574 FormatToken *FormatTok;
Alexander Kornienkoe3276842012-12-07 16:15:44 +0000575 bool GreaterStashed;
Manuel Klimek9043c742013-05-27 15:23:34 +0000576 unsigned TrailingWhitespace;
Alexander Kornienkoe3276842012-12-07 16:15:44 +0000577 Lexer &Lex;
578 SourceManager &SourceMgr;
579 IdentifierTable IdentTable;
Alexander Kornienkoffcc0102013-06-05 14:09:10 +0000580 encoding::Encoding Encoding;
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000581 llvm::SpecificBumpPtrAllocator<FormatToken> Allocator;
582 SmallVector<FormatToken *, 16> Tokens;
Alexander Kornienkoe3276842012-12-07 16:15:44 +0000583
Daniel Jasper8369aa52013-07-16 20:28:33 +0000584 void readRawToken(FormatToken &Tok) {
585 Lex.LexFromRawLexer(Tok.Tok);
586 Tok.TokenText = StringRef(SourceMgr.getCharacterData(Tok.Tok.getLocation()),
587 Tok.Tok.getLength());
588
589 // For formatting, treat unterminated string literals like normal string
590 // literals.
591 if (Tok.is(tok::unknown) && !Tok.TokenText.empty() &&
592 Tok.TokenText[0] == '"') {
593 Tok.Tok.setKind(tok::string_literal);
594 Tok.IsUnterminatedLiteral = true;
595 }
Alexander Kornienkoe3276842012-12-07 16:15:44 +0000596 }
597};
598
Daniel Jasperf7935112012-12-03 18:12:45 +0000599class Formatter : public UnwrappedLineConsumer {
600public:
Daniel Jasperd2ae41a2013-05-15 08:14:19 +0000601 Formatter(const FormatStyle &Style, Lexer &Lex, SourceManager &SourceMgr,
Daniel Jasperf7935112012-12-03 18:12:45 +0000602 const std::vector<CharSourceRange> &Ranges)
Daniel Jasperd2ae41a2013-05-15 08:14:19 +0000603 : Style(Style), Lex(Lex), SourceMgr(SourceMgr),
Alexander Kornienkoffcc0102013-06-05 14:09:10 +0000604 Whitespaces(SourceMgr, Style), Ranges(Ranges),
605 Encoding(encoding::detectEncoding(Lex.getBuffer())) {
Daniel Jasperfa21c072013-07-15 14:33:14 +0000606 DEBUG(llvm::dbgs() << "File encoding: "
607 << (Encoding == encoding::Encoding_UTF8 ? "UTF8"
608 : "unknown")
609 << "\n");
Alexander Kornienkoffcc0102013-06-05 14:09:10 +0000610 }
Daniel Jasperf7935112012-12-03 18:12:45 +0000611
Daniel Jasperfd8c4b12013-01-11 14:23:32 +0000612 virtual ~Formatter() {}
Daniel Jasper61bd3a12012-12-04 21:05:31 +0000613
Alexander Kornienko62b85b92013-03-13 14:41:29 +0000614 tooling::Replacements format() {
Alexander Kornienkoffcc0102013-06-05 14:09:10 +0000615 FormatTokenLexer Tokens(Lex, SourceMgr, Encoding);
Manuel Klimek15dfe7a2013-05-28 11:55:06 +0000616
617 UnwrappedLineParser Parser(Style, Tokens.lex(), *this);
Manuel Klimek1a18c402013-04-12 14:13:36 +0000618 bool StructuralError = Parser.parse();
Alexander Kornienkoffcc0102013-06-05 14:09:10 +0000619 TokenAnnotator Annotator(Style, Tokens.getIdentTable().get("in"));
Alexander Kornienko62b85b92013-03-13 14:41:29 +0000620 for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
621 Annotator.annotate(AnnotatedLines[i]);
622 }
623 deriveLocalStyle();
624 for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
625 Annotator.calculateFormattingInformation(AnnotatedLines[i]);
626 }
Daniel Jasperb67cc422013-04-09 17:46:55 +0000627
628 // Adapt level to the next line if this is a comment.
629 // FIXME: Can/should this be done in the UnwrappedLineParser?
Alexander Kornienko1efe0a02013-07-04 14:47:51 +0000630 const AnnotatedLine *NextNonCommentLine = NULL;
Daniel Jasperb67cc422013-04-09 17:46:55 +0000631 for (unsigned i = AnnotatedLines.size() - 1; i > 0; --i) {
Alexander Kornienko1efe0a02013-07-04 14:47:51 +0000632 if (NextNonCommentLine && AnnotatedLines[i].First->is(tok::comment) &&
Manuel Klimek6e6310e2013-05-29 14:47:47 +0000633 !AnnotatedLines[i].First->Next)
Alexander Kornienko1efe0a02013-07-04 14:47:51 +0000634 AnnotatedLines[i].Level = NextNonCommentLine->Level;
Daniel Jasperb67cc422013-04-09 17:46:55 +0000635 else
Daniel Jasper3ac9b9e2013-07-08 14:34:09 +0000636 NextNonCommentLine = AnnotatedLines[i].First->isNot(tok::r_brace)
637 ? &AnnotatedLines[i]
638 : NULL;
Daniel Jasperb67cc422013-04-09 17:46:55 +0000639 }
640
Alexander Kornienko62b85b92013-03-13 14:41:29 +0000641 std::vector<int> IndentForLevel;
642 bool PreviousLineWasTouched = false;
Manuel Klimek6e6310e2013-05-29 14:47:47 +0000643 const FormatToken *PreviousLineLastToken = 0;
Daniel Jasper1cb530f2013-05-10 13:00:49 +0000644 bool FormatPPDirective = false;
Alexander Kornienko62b85b92013-03-13 14:41:29 +0000645 for (std::vector<AnnotatedLine>::iterator I = AnnotatedLines.begin(),
646 E = AnnotatedLines.end();
647 I != E; ++I) {
648 const AnnotatedLine &TheLine = *I;
Manuel Klimek6e6310e2013-05-29 14:47:47 +0000649 const FormatToken *FirstTok = TheLine.First;
650 int Offset = getIndentOffset(*TheLine.First);
Daniel Jasper1cb530f2013-05-10 13:00:49 +0000651
652 // Check whether this line is part of a formatted preprocessor directive.
Manuel Klimek591ab5a2013-05-28 13:42:28 +0000653 if (FirstTok->HasUnescapedNewline)
Daniel Jasper1cb530f2013-05-10 13:00:49 +0000654 FormatPPDirective = false;
655 if (!FormatPPDirective && TheLine.InPPDirective &&
656 (touchesLine(TheLine) || touchesPPDirective(I + 1, E)))
657 FormatPPDirective = true;
658
Daniel Jasper12f9d8e2013-05-14 09:30:02 +0000659 // Determine indent and try to merge multiple unwrapped lines.
Alexander Kornienko62b85b92013-03-13 14:41:29 +0000660 while (IndentForLevel.size() <= TheLine.Level)
661 IndentForLevel.push_back(-1);
662 IndentForLevel.resize(TheLine.Level + 1);
Daniel Jasper12f9d8e2013-05-14 09:30:02 +0000663 unsigned Indent = getIndent(IndentForLevel, TheLine.Level);
664 if (static_cast<int>(Indent) + Offset >= 0)
665 Indent += Offset;
666 tryFitMultipleLinesInOne(Indent, I, E);
667
Manuel Klimek591ab5a2013-05-28 13:42:28 +0000668 bool WasMoved = PreviousLineWasTouched && FirstTok->NewlinesBefore == 0;
Manuel Klimek6e6310e2013-05-29 14:47:47 +0000669 if (TheLine.First->is(tok::eof)) {
Alexander Kornienko62b85b92013-03-13 14:41:29 +0000670 if (PreviousLineWasTouched) {
Manuel Klimek591ab5a2013-05-28 13:42:28 +0000671 unsigned NewLines = std::min(FirstTok->NewlinesBefore, 1u);
Manuel Klimek6e6310e2013-05-29 14:47:47 +0000672 Whitespaces.replaceWhitespace(*TheLine.First, NewLines, /*Indent*/ 0,
Manuel Klimek4fe43002013-05-22 12:51:29 +0000673 /*TargetColumn*/ 0);
Alexander Kornienko62b85b92013-03-13 14:41:29 +0000674 }
675 } else if (TheLine.Type != LT_Invalid &&
Daniel Jasper1cb530f2013-05-10 13:00:49 +0000676 (WasMoved || FormatPPDirective || touchesLine(TheLine))) {
Alexander Kornienko62b85b92013-03-13 14:41:29 +0000677 unsigned LevelIndent = getIndent(IndentForLevel, TheLine.Level);
Manuel Klimek591ab5a2013-05-28 13:42:28 +0000678 if (FirstTok->WhitespaceRange.isValid() &&
Manuel Klimek1a18c402013-04-12 14:13:36 +0000679 // Insert a break even if there is a structural error in case where
680 // we break apart a line consisting of multiple unwrapped lines.
Manuel Klimek591ab5a2013-05-28 13:42:28 +0000681 (FirstTok->NewlinesBefore == 0 || !StructuralError)) {
Manuel Klimek6e6310e2013-05-29 14:47:47 +0000682 formatFirstToken(*TheLine.First, PreviousLineLastToken, Indent,
Manuel Klimek4fe43002013-05-22 12:51:29 +0000683 TheLine.InPPDirective);
Manuel Klimek1a18c402013-04-12 14:13:36 +0000684 } else {
685 Indent = LevelIndent =
Manuel Klimek591ab5a2013-05-28 13:42:28 +0000686 SourceMgr.getSpellingColumnNumber(FirstTok->Tok.getLocation()) -
687 1;
Alexander Kornienko62b85b92013-03-13 14:41:29 +0000688 }
Daniel Jasperde0328a2013-08-16 11:20:30 +0000689 ContinuationIndenter Indenter(Style, SourceMgr, TheLine, Indent,
690 Whitespaces, Encoding,
691 BinPackInconclusiveFunctions);
692
693 // If everything fits on a single line, just put it there.
694 unsigned ColumnLimit = Style.ColumnLimit;
695 if ((I + 1) != E && (I + 1)->InPPDirective &&
696 !(I + 1)->First->HasUnescapedNewline)
697 ColumnLimit = Indenter.getColumnLimit();
698
699 if (I->Last->TotalLength + Indent <= ColumnLimit) {
700 LineState State = Indenter.getInitialState();
701 while (State.NextToken != NULL)
702 Indenter.addTokenToState(State, false, false);
703 } else if (Style.ColumnLimit == 0) {
704 NoColumnLimitFormatter Formatter(&Indenter);
705 Formatter.format();
706 } else {
707 UnwrappedLineFormatter Formatter(&Indenter, Style, TheLine);
708 Formatter.format();
709 }
710
Alexander Kornienko62b85b92013-03-13 14:41:29 +0000711 IndentForLevel[TheLine.Level] = LevelIndent;
712 PreviousLineWasTouched = true;
713 } else {
Manuel Klimek4fe43002013-05-22 12:51:29 +0000714 // Format the first token if necessary, and notify the WhitespaceManager
715 // about the unchanged whitespace.
Manuel Klimek6e6310e2013-05-29 14:47:47 +0000716 for (const FormatToken *Tok = TheLine.First; Tok != NULL;
717 Tok = Tok->Next) {
718 if (Tok == TheLine.First &&
719 (Tok->NewlinesBefore > 0 || Tok->IsFirst)) {
720 unsigned LevelIndent =
721 SourceMgr.getSpellingColumnNumber(Tok->Tok.getLocation()) - 1;
Manuel Klimek4fe43002013-05-22 12:51:29 +0000722 // Remove trailing whitespace of the previous line if it was
723 // touched.
724 if (PreviousLineWasTouched || touchesEmptyLineBefore(TheLine)) {
725 formatFirstToken(*Tok, PreviousLineLastToken, LevelIndent,
726 TheLine.InPPDirective);
727 } else {
Manuel Klimek6e6310e2013-05-29 14:47:47 +0000728 Whitespaces.addUntouchableToken(*Tok, TheLine.InPPDirective);
Manuel Klimek4fe43002013-05-22 12:51:29 +0000729 }
Daniel Jasper12f9d8e2013-05-14 09:30:02 +0000730
Manuel Klimek4fe43002013-05-22 12:51:29 +0000731 if (static_cast<int>(LevelIndent) - Offset >= 0)
732 LevelIndent -= Offset;
733 if (Tok->isNot(tok::comment))
734 IndentForLevel[TheLine.Level] = LevelIndent;
735 } else {
Manuel Klimek6e6310e2013-05-29 14:47:47 +0000736 Whitespaces.addUntouchableToken(*Tok, TheLine.InPPDirective);
Manuel Klimek4fe43002013-05-22 12:51:29 +0000737 }
Alexander Kornienko62b85b92013-03-13 14:41:29 +0000738 }
739 // If we did not reformat this unwrapped line, the column at the end of
740 // the last token is unchanged - thus, we can calculate the end of the
741 // last token.
Alexander Kornienko62b85b92013-03-13 14:41:29 +0000742 PreviousLineWasTouched = false;
743 }
Alexander Kornienkofd433362013-03-27 17:08:02 +0000744 PreviousLineLastToken = I->Last;
Alexander Kornienko62b85b92013-03-13 14:41:29 +0000745 }
746 return Whitespaces.generateReplacements();
747 }
748
749private:
Daniel Jasper7fce3ab2013-02-06 14:22:40 +0000750 void deriveLocalStyle() {
751 unsigned CountBoundToVariable = 0;
752 unsigned CountBoundToType = 0;
753 bool HasCpp03IncompatibleFormat = false;
Daniel Jasperb10cbc42013-07-10 14:02:49 +0000754 bool HasBinPackedFunction = false;
755 bool HasOnePerLineFunction = false;
Daniel Jasper7fce3ab2013-02-06 14:22:40 +0000756 for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
Manuel Klimek6e6310e2013-05-29 14:47:47 +0000757 if (!AnnotatedLines[i].First->Next)
Daniel Jasper7fce3ab2013-02-06 14:22:40 +0000758 continue;
Manuel Klimek6e6310e2013-05-29 14:47:47 +0000759 FormatToken *Tok = AnnotatedLines[i].First->Next;
760 while (Tok->Next) {
Daniel Jasper7fce3ab2013-02-06 14:22:40 +0000761 if (Tok->Type == TT_PointerOrReference) {
Manuel Klimek6e6310e2013-05-29 14:47:47 +0000762 bool SpacesBefore =
763 Tok->WhitespaceRange.getBegin() != Tok->WhitespaceRange.getEnd();
764 bool SpacesAfter = Tok->Next->WhitespaceRange.getBegin() !=
765 Tok->Next->WhitespaceRange.getEnd();
Daniel Jasper7fce3ab2013-02-06 14:22:40 +0000766 if (SpacesBefore && !SpacesAfter)
767 ++CountBoundToVariable;
768 else if (!SpacesBefore && SpacesAfter)
769 ++CountBoundToType;
770 }
771
Daniel Jasper400adc62013-02-08 15:28:42 +0000772 if (Tok->Type == TT_TemplateCloser &&
Manuel Klimek6e6310e2013-05-29 14:47:47 +0000773 Tok->Previous->Type == TT_TemplateCloser &&
774 Tok->WhitespaceRange.getBegin() == Tok->WhitespaceRange.getEnd())
Daniel Jasper7fce3ab2013-02-06 14:22:40 +0000775 HasCpp03IncompatibleFormat = true;
Daniel Jasperb10cbc42013-07-10 14:02:49 +0000776
777 if (Tok->PackingKind == PPK_BinPacked)
778 HasBinPackedFunction = true;
779 if (Tok->PackingKind == PPK_OnePerLine)
780 HasOnePerLineFunction = true;
781
Manuel Klimek6e6310e2013-05-29 14:47:47 +0000782 Tok = Tok->Next;
Daniel Jasper7fce3ab2013-02-06 14:22:40 +0000783 }
784 }
785 if (Style.DerivePointerBinding) {
786 if (CountBoundToType > CountBoundToVariable)
787 Style.PointerBindsToType = true;
788 else if (CountBoundToType < CountBoundToVariable)
789 Style.PointerBindsToType = false;
790 }
791 if (Style.Standard == FormatStyle::LS_Auto) {
792 Style.Standard = HasCpp03IncompatibleFormat ? FormatStyle::LS_Cpp11
793 : FormatStyle::LS_Cpp03;
794 }
Daniel Jasperb10cbc42013-07-10 14:02:49 +0000795 BinPackInconclusiveFunctions =
796 HasBinPackedFunction || !HasOnePerLineFunction;
Daniel Jasper7fce3ab2013-02-06 14:22:40 +0000797 }
798
Manuel Klimekb95f5452013-02-08 17:38:27 +0000799 /// \brief Get the indent of \p Level from \p IndentForLevel.
800 ///
801 /// \p IndentForLevel must contain the indent for the level \c l
802 /// at \p IndentForLevel[l], or a value < 0 if the indent for
803 /// that level is unknown.
Daniel Jasper687af3b2013-02-14 14:26:07 +0000804 unsigned getIndent(const std::vector<int> IndentForLevel, unsigned Level) {
Manuel Klimekb95f5452013-02-08 17:38:27 +0000805 if (IndentForLevel[Level] != -1)
806 return IndentForLevel[Level];
Manuel Klimekd076dcd2013-02-08 19:53:32 +0000807 if (Level == 0)
808 return 0;
Manuel Klimek13b97d82013-05-13 08:42:42 +0000809 return getIndent(IndentForLevel, Level - 1) + Style.IndentWidth;
Manuel Klimekb95f5452013-02-08 17:38:27 +0000810 }
811
812 /// \brief Get the offset of the line relatively to the level.
813 ///
814 /// For example, 'public:' labels in classes are offset by 1 or 2
815 /// characters to the left from their level.
Manuel Klimek6e6310e2013-05-29 14:47:47 +0000816 int getIndentOffset(const FormatToken &RootToken) {
Alexander Kornienkofd433362013-03-27 17:08:02 +0000817 if (RootToken.isAccessSpecifier(false) || RootToken.isObjCAccessSpecifier())
Manuel Klimekb95f5452013-02-08 17:38:27 +0000818 return Style.AccessModifierOffset;
819 return 0;
820 }
821
Manuel Klimekf4ab9ef2013-01-11 17:54:10 +0000822 /// \brief Tries to merge lines into one.
823 ///
824 /// This will change \c Line and \c AnnotatedLine to contain the merged line,
825 /// if possible; note that \c I will be incremented when lines are merged.
Daniel Jaspera67a8f02013-01-16 10:41:46 +0000826 void tryFitMultipleLinesInOne(unsigned Indent,
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +0000827 std::vector<AnnotatedLine>::iterator &I,
828 std::vector<AnnotatedLine>::iterator E) {
Daniel Jaspera67a8f02013-01-16 10:41:46 +0000829 // We can never merge stuff if there are trailing line comments.
830 if (I->Last->Type == TT_LineComment)
831 return;
832
Daniel Jasperffefb3d2013-07-24 13:10:59 +0000833 if (Indent > Style.ColumnLimit)
834 return;
835
Daniel Jasperc22f5b42013-02-28 11:05:57 +0000836 unsigned Limit = Style.ColumnLimit - Indent;
Daniel Jasper12ef4e52013-02-21 21:33:55 +0000837 // If we already exceed the column limit, we set 'Limit' to 0. The different
838 // tryMerge..() functions can then decide whether to still do merging.
839 Limit = I->Last->TotalLength > Limit ? 0 : Limit - I->Last->TotalLength;
Daniel Jasperc36492b2013-01-16 07:02:34 +0000840
Daniel Jasperd41ee2d2013-01-21 14:18:28 +0000841 if (I + 1 == E || (I + 1)->Type == LT_Invalid)
Daniel Jaspera67a8f02013-01-16 10:41:46 +0000842 return;
Manuel Klimekf4ab9ef2013-01-11 17:54:10 +0000843
Daniel Jasperabca58c2013-05-15 14:09:55 +0000844 if (I->Last->is(tok::l_brace)) {
Daniel Jasper25837aa2013-01-14 14:14:23 +0000845 tryMergeSimpleBlock(I, E, Limit);
Daniel Jasper3a685df2013-05-16 12:12:21 +0000846 } else if (Style.AllowShortIfStatementsOnASingleLine &&
Manuel Klimek6e6310e2013-05-29 14:47:47 +0000847 I->First->is(tok::kw_if)) {
Daniel Jasper3a685df2013-05-16 12:12:21 +0000848 tryMergeSimpleControlStatement(I, E, Limit);
849 } else if (Style.AllowShortLoopsOnASingleLine &&
Manuel Klimek6e6310e2013-05-29 14:47:47 +0000850 I->First->isOneOf(tok::kw_for, tok::kw_while)) {
Daniel Jasper3a685df2013-05-16 12:12:21 +0000851 tryMergeSimpleControlStatement(I, E, Limit);
Manuel Klimek6e6310e2013-05-29 14:47:47 +0000852 } else if (I->InPPDirective &&
853 (I->First->HasUnescapedNewline || I->First->IsFirst)) {
Daniel Jasper39825ea2013-01-14 15:40:57 +0000854 tryMergeSimplePPDirective(I, E, Limit);
Daniel Jasper25837aa2013-01-14 14:14:23 +0000855 }
Daniel Jasper25837aa2013-01-14 14:14:23 +0000856 }
857
Daniel Jasper39825ea2013-01-14 15:40:57 +0000858 void tryMergeSimplePPDirective(std::vector<AnnotatedLine>::iterator &I,
859 std::vector<AnnotatedLine>::iterator E,
860 unsigned Limit) {
Daniel Jasper12ef4e52013-02-21 21:33:55 +0000861 if (Limit == 0)
862 return;
Daniel Jasper39825ea2013-01-14 15:40:57 +0000863 AnnotatedLine &Line = *I;
Manuel Klimek6e6310e2013-05-29 14:47:47 +0000864 if (!(I + 1)->InPPDirective || (I + 1)->First->HasUnescapedNewline)
Daniel Jasper2ab0d012013-01-14 15:52:06 +0000865 return;
Daniel Jasper39825ea2013-01-14 15:40:57 +0000866 if (I + 2 != E && (I + 2)->InPPDirective &&
Manuel Klimek6e6310e2013-05-29 14:47:47 +0000867 !(I + 2)->First->HasUnescapedNewline)
Daniel Jasper39825ea2013-01-14 15:40:57 +0000868 return;
Manuel Klimeka4fe1c12013-01-21 16:42:44 +0000869 if (1 + (I + 1)->Last->TotalLength > Limit)
Daniel Jaspera67a8f02013-01-16 10:41:46 +0000870 return;
Daniel Jasper39825ea2013-01-14 15:40:57 +0000871 join(Line, *(++I));
872 }
873
Daniel Jasper3a685df2013-05-16 12:12:21 +0000874 void tryMergeSimpleControlStatement(std::vector<AnnotatedLine>::iterator &I,
875 std::vector<AnnotatedLine>::iterator E,
876 unsigned Limit) {
Daniel Jasper12ef4e52013-02-21 21:33:55 +0000877 if (Limit == 0)
878 return;
Manuel Klimeka027f302013-08-07 19:20:45 +0000879 if (Style.BreakBeforeBraces == FormatStyle::BS_Allman &&
880 (I + 1)->First->is(tok::l_brace))
881 return;
Manuel Klimekda087612013-01-18 14:46:43 +0000882 if ((I + 1)->InPPDirective != I->InPPDirective ||
Manuel Klimek6e6310e2013-05-29 14:47:47 +0000883 ((I + 1)->InPPDirective && (I + 1)->First->HasUnescapedNewline))
Manuel Klimekda087612013-01-18 14:46:43 +0000884 return;
Daniel Jasper25837aa2013-01-14 14:14:23 +0000885 AnnotatedLine &Line = *I;
Daniel Jasperc36492b2013-01-16 07:02:34 +0000886 if (Line.Last->isNot(tok::r_paren))
887 return;
Manuel Klimeka4fe1c12013-01-21 16:42:44 +0000888 if (1 + (I + 1)->Last->TotalLength > Limit)
Daniel Jasper25837aa2013-01-14 14:14:23 +0000889 return;
Manuel Klimek6e6310e2013-05-29 14:47:47 +0000890 if ((I + 1)->First->isOneOf(tok::semi, tok::kw_if, tok::kw_for,
891 tok::kw_while) ||
892 (I + 1)->First->Type == TT_LineComment)
Daniel Jasper25837aa2013-01-14 14:14:23 +0000893 return;
894 // Only inline simple if's (no nested if or else).
Manuel Klimek6e6310e2013-05-29 14:47:47 +0000895 if (I + 2 != E && Line.First->is(tok::kw_if) &&
896 (I + 2)->First->is(tok::kw_else))
Daniel Jasper25837aa2013-01-14 14:14:23 +0000897 return;
898 join(Line, *(++I));
899 }
900
901 void tryMergeSimpleBlock(std::vector<AnnotatedLine>::iterator &I,
Daniel Jasperbbc84152013-01-29 11:27:30 +0000902 std::vector<AnnotatedLine>::iterator E,
903 unsigned Limit) {
Daniel Jasperabca58c2013-05-15 14:09:55 +0000904 // No merging if the brace already is on the next line.
905 if (Style.BreakBeforeBraces != FormatStyle::BS_Attach)
906 return;
907
Manuel Klimekf4ab9ef2013-01-11 17:54:10 +0000908 // First, check that the current line allows merging. This is the case if
909 // we're not in a control flow statement and the last token is an opening
910 // brace.
Daniel Jasper25837aa2013-01-14 14:14:23 +0000911 AnnotatedLine &Line = *I;
Manuel Klimek6e6310e2013-05-29 14:47:47 +0000912 if (Line.First->isOneOf(tok::kw_if, tok::kw_while, tok::kw_do, tok::r_brace,
913 tok::kw_else, tok::kw_try, tok::kw_catch,
Daniel Jaspera9eb2aa2013-05-31 14:56:20 +0000914 tok::kw_for,
Manuel Klimek6e6310e2013-05-29 14:47:47 +0000915 // This gets rid of all ObjC @ keywords and methods.
916 tok::at, tok::minus, tok::plus))
Daniel Jasper25837aa2013-01-14 14:14:23 +0000917 return;
Manuel Klimekf4ab9ef2013-01-11 17:54:10 +0000918
Manuel Klimek6e6310e2013-05-29 14:47:47 +0000919 FormatToken *Tok = (I + 1)->First;
Daniel Jaspera9eb2aa2013-05-31 14:56:20 +0000920 if (Tok->is(tok::r_brace) && !Tok->MustBreakBefore &&
Alexander Kornienko1efe0a02013-07-04 14:47:51 +0000921 (Tok->getNextNonComment() == NULL ||
922 Tok->getNextNonComment()->is(tok::semi))) {
Daniel Jasper12ef4e52013-02-21 21:33:55 +0000923 // We merge empty blocks even if the line exceeds the column limit.
Daniel Jaspereef30492013-02-11 12:36:37 +0000924 Tok->SpacesRequiredBefore = 0;
Daniel Jasper12ef4e52013-02-21 21:33:55 +0000925 Tok->CanBreakBefore = true;
Manuel Klimeka4fe1c12013-01-21 16:42:44 +0000926 join(Line, *(I + 1));
927 I += 1;
Daniel Jaspera9eb2aa2013-05-31 14:56:20 +0000928 } else if (Limit != 0 && Line.First->isNot(tok::kw_namespace)) {
Manuel Klimeka4fe1c12013-01-21 16:42:44 +0000929 // Check that we still have three lines and they fit into the limit.
930 if (I + 2 == E || (I + 2)->Type == LT_Invalid ||
931 !nextTwoLinesFitInto(I, Limit))
Daniel Jasper25837aa2013-01-14 14:14:23 +0000932 return;
Manuel Klimekf4ab9ef2013-01-11 17:54:10 +0000933
Manuel Klimeka4fe1c12013-01-21 16:42:44 +0000934 // Second, check that the next line does not contain any braces - if it
935 // does, readability declines when putting it into a single line.
936 if ((I + 1)->Last->Type == TT_LineComment || Tok->MustBreakBefore)
937 return;
938 do {
Alexander Kornienko62b85b92013-03-13 14:41:29 +0000939 if (Tok->isOneOf(tok::l_brace, tok::r_brace))
Manuel Klimeka4fe1c12013-01-21 16:42:44 +0000940 return;
Manuel Klimek6e6310e2013-05-29 14:47:47 +0000941 Tok = Tok->Next;
Manuel Klimeka4fe1c12013-01-21 16:42:44 +0000942 } while (Tok != NULL);
Manuel Klimekf4ab9ef2013-01-11 17:54:10 +0000943
Manuel Klimeka4fe1c12013-01-21 16:42:44 +0000944 // Last, check that the third line contains a single closing brace.
Manuel Klimek6e6310e2013-05-29 14:47:47 +0000945 Tok = (I + 2)->First;
Alexander Kornienko1efe0a02013-07-04 14:47:51 +0000946 if (Tok->getNextNonComment() != NULL || Tok->isNot(tok::r_brace) ||
Manuel Klimeka4fe1c12013-01-21 16:42:44 +0000947 Tok->MustBreakBefore)
948 return;
949
950 join(Line, *(I + 1));
951 join(Line, *(I + 2));
952 I += 2;
Manuel Klimekf4ab9ef2013-01-11 17:54:10 +0000953 }
Daniel Jasper25837aa2013-01-14 14:14:23 +0000954 }
955
956 bool nextTwoLinesFitInto(std::vector<AnnotatedLine>::iterator I,
957 unsigned Limit) {
Manuel Klimeka4fe1c12013-01-21 16:42:44 +0000958 return 1 + (I + 1)->Last->TotalLength + 1 + (I + 2)->Last->TotalLength <=
959 Limit;
Manuel Klimekf4ab9ef2013-01-11 17:54:10 +0000960 }
961
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +0000962 void join(AnnotatedLine &A, const AnnotatedLine &B) {
Manuel Klimek6e6310e2013-05-29 14:47:47 +0000963 assert(!A.Last->Next);
964 assert(!B.First->Previous);
965 A.Last->Next = B.First;
966 B.First->Previous = A.Last;
967 unsigned LengthA = A.Last->TotalLength + B.First->SpacesRequiredBefore;
968 for (FormatToken *Tok = B.First; Tok; Tok = Tok->Next) {
969 Tok->TotalLength += LengthA;
970 A.Last = Tok;
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +0000971 }
Manuel Klimek51bd6ec2013-01-10 19:49:59 +0000972 }
973
Daniel Jasper97b89482013-03-13 07:49:51 +0000974 bool touchesRanges(const CharSourceRange &Range) {
Daniel Jasperf71cf3b2013-03-07 20:50:00 +0000975 for (unsigned i = 0, e = Ranges.size(); i != e; ++i) {
976 if (!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(),
977 Ranges[i].getBegin()) &&
978 !SourceMgr.isBeforeInTranslationUnit(Ranges[i].getEnd(),
979 Range.getBegin()))
980 return true;
981 }
982 return false;
983 }
984
985 bool touchesLine(const AnnotatedLine &TheLine) {
Manuel Klimek6e6310e2013-05-29 14:47:47 +0000986 const FormatToken *First = TheLine.First;
987 const FormatToken *Last = TheLine.Last;
Daniel Jaspercdd06622013-05-14 10:31:09 +0000988 CharSourceRange LineRange = CharSourceRange::getCharRange(
Manuel Klimek5c24cca2013-05-23 10:56:37 +0000989 First->WhitespaceRange.getBegin().getLocWithOffset(
990 First->LastNewlineOffset),
Alexander Kornienkoee4ca9b2013-06-07 17:45:07 +0000991 Last->Tok.getLocation().getLocWithOffset(Last->TokenText.size() - 1));
Daniel Jasperf71cf3b2013-03-07 20:50:00 +0000992 return touchesRanges(LineRange);
993 }
994
Daniel Jasper1cb530f2013-05-10 13:00:49 +0000995 bool touchesPPDirective(std::vector<AnnotatedLine>::iterator I,
996 std::vector<AnnotatedLine>::iterator E) {
997 for (; I != E; ++I) {
Manuel Klimek6e6310e2013-05-29 14:47:47 +0000998 if (I->First->HasUnescapedNewline)
Daniel Jasper1cb530f2013-05-10 13:00:49 +0000999 return false;
1000 if (touchesLine(*I))
1001 return true;
1002 }
1003 return false;
1004 }
1005
Daniel Jasperf71cf3b2013-03-07 20:50:00 +00001006 bool touchesEmptyLineBefore(const AnnotatedLine &TheLine) {
Manuel Klimek6e6310e2013-05-29 14:47:47 +00001007 const FormatToken *First = TheLine.First;
Daniel Jasperf71cf3b2013-03-07 20:50:00 +00001008 CharSourceRange LineRange = CharSourceRange::getCharRange(
Manuel Klimek5c24cca2013-05-23 10:56:37 +00001009 First->WhitespaceRange.getBegin(),
1010 First->WhitespaceRange.getBegin().getLocWithOffset(
1011 First->LastNewlineOffset));
Daniel Jasperf71cf3b2013-03-07 20:50:00 +00001012 return touchesRanges(LineRange);
Manuel Klimek51bd6ec2013-01-10 19:49:59 +00001013 }
1014
1015 virtual void consumeUnwrappedLine(const UnwrappedLine &TheLine) {
Daniel Jasperdaffc0d2013-01-16 09:10:19 +00001016 AnnotatedLines.push_back(AnnotatedLine(TheLine));
Daniel Jasperf7935112012-12-03 18:12:45 +00001017 }
1018
Manuel Klimek0b689fd2013-01-10 18:45:26 +00001019 /// \brief Add a new line and the required indent before the first Token
1020 /// of the \c UnwrappedLine if there was no structural parsing error.
1021 /// Returns the indent level of the \c UnwrappedLine.
Manuel Klimek6e6310e2013-05-29 14:47:47 +00001022 void formatFirstToken(const FormatToken &RootToken,
1023 const FormatToken *PreviousToken, unsigned Indent,
Manuel Klimek4fe43002013-05-22 12:51:29 +00001024 bool InPPDirective) {
Daniel Jasperbbc84152013-01-29 11:27:30 +00001025 unsigned Newlines =
Manuel Klimek6e6310e2013-05-29 14:47:47 +00001026 std::min(RootToken.NewlinesBefore, Style.MaxEmptyLinesToKeep + 1);
Daniel Jasper1027c6e2013-06-03 16:16:41 +00001027 // Remove empty lines before "}" where applicable.
1028 if (RootToken.is(tok::r_brace) &&
1029 (!RootToken.Next ||
1030 (RootToken.Next->is(tok::semi) && !RootToken.Next->Next)))
1031 Newlines = std::min(Newlines, 1u);
Manuel Klimek6e6310e2013-05-29 14:47:47 +00001032 if (Newlines == 0 && !RootToken.IsFirst)
Manuel Klimek0b689fd2013-01-10 18:45:26 +00001033 Newlines = 1;
Manuel Klimek0b689fd2013-01-10 18:45:26 +00001034
Manuel Klimek4fe43002013-05-22 12:51:29 +00001035 // Insert extra new line before access specifiers.
1036 if (PreviousToken && PreviousToken->isOneOf(tok::semi, tok::r_brace) &&
Manuel Klimek6e6310e2013-05-29 14:47:47 +00001037 RootToken.isAccessSpecifier() && RootToken.NewlinesBefore == 1)
Manuel Klimek4fe43002013-05-22 12:51:29 +00001038 ++Newlines;
Alexander Kornienkofd433362013-03-27 17:08:02 +00001039
Manuel Klimek6e6310e2013-05-29 14:47:47 +00001040 Whitespaces.replaceWhitespace(
1041 RootToken, Newlines, Indent, Indent,
1042 InPPDirective && !RootToken.HasUnescapedNewline);
Manuel Klimek0b689fd2013-01-10 18:45:26 +00001043 }
1044
Daniel Jasperf7935112012-12-03 18:12:45 +00001045 FormatStyle Style;
1046 Lexer &Lex;
1047 SourceManager &SourceMgr;
Daniel Jasperaa701fa2013-01-18 08:44:07 +00001048 WhitespaceManager Whitespaces;
Daniel Jasperf7935112012-12-03 18:12:45 +00001049 std::vector<CharSourceRange> Ranges;
Daniel Jasperf1e4b7d2013-01-14 13:08:07 +00001050 std::vector<AnnotatedLine> AnnotatedLines;
Alexander Kornienkoffcc0102013-06-05 14:09:10 +00001051
1052 encoding::Encoding Encoding;
Daniel Jasperb10cbc42013-07-10 14:02:49 +00001053 bool BinPackInconclusiveFunctions;
Daniel Jasperf7935112012-12-03 18:12:45 +00001054};
1055
Craig Topperaf35e852013-06-30 22:29:28 +00001056} // end anonymous namespace
1057
Alexander Kornienkocb45bc12013-04-15 14:28:00 +00001058tooling::Replacements reformat(const FormatStyle &Style, Lexer &Lex,
1059 SourceManager &SourceMgr,
Daniel Jasperd2ae41a2013-05-15 08:14:19 +00001060 std::vector<CharSourceRange> Ranges) {
1061 Formatter formatter(Style, Lex, SourceMgr, Ranges);
Daniel Jasperf7935112012-12-03 18:12:45 +00001062 return formatter.format();
1063}
1064
Daniel Jasperec04c0d2013-05-16 10:40:07 +00001065tooling::Replacements reformat(const FormatStyle &Style, StringRef Code,
1066 std::vector<tooling::Range> Ranges,
1067 StringRef FileName) {
1068 FileManager Files((FileSystemOptions()));
1069 DiagnosticsEngine Diagnostics(
1070 IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
1071 new DiagnosticOptions);
1072 SourceManager SourceMgr(Diagnostics, Files);
1073 llvm::MemoryBuffer *Buf = llvm::MemoryBuffer::getMemBuffer(Code, FileName);
1074 const clang::FileEntry *Entry =
1075 Files.getVirtualFile(FileName, Buf->getBufferSize(), 0);
1076 SourceMgr.overrideFileContents(Entry, Buf);
1077 FileID ID =
1078 SourceMgr.createFileID(Entry, SourceLocation(), clang::SrcMgr::C_User);
Alexander Kornienko1e808872013-06-28 12:51:24 +00001079 Lexer Lex(ID, SourceMgr.getBuffer(ID), SourceMgr,
1080 getFormattingLangOpts(Style.Standard));
Daniel Jasperec04c0d2013-05-16 10:40:07 +00001081 SourceLocation StartOfFile = SourceMgr.getLocForStartOfFile(ID);
1082 std::vector<CharSourceRange> CharRanges;
1083 for (unsigned i = 0, e = Ranges.size(); i != e; ++i) {
1084 SourceLocation Start = StartOfFile.getLocWithOffset(Ranges[i].getOffset());
1085 SourceLocation End = Start.getLocWithOffset(Ranges[i].getLength());
1086 CharRanges.push_back(CharSourceRange::getCharRange(Start, End));
1087 }
1088 return reformat(Style, Lex, SourceMgr, CharRanges);
1089}
1090
Alexander Kornienko1e808872013-06-28 12:51:24 +00001091LangOptions getFormattingLangOpts(FormatStyle::LanguageStandard Standard) {
Daniel Jasperc1fa2812013-01-10 13:08:12 +00001092 LangOptions LangOpts;
1093 LangOpts.CPlusPlus = 1;
Alexander Kornienko1e808872013-06-28 12:51:24 +00001094 LangOpts.CPlusPlus11 = Standard == FormatStyle::LS_Cpp03 ? 0 : 1;
Daniel Jasper55213652013-03-22 10:01:29 +00001095 LangOpts.LineComment = 1;
Daniel Jasperc1fa2812013-01-10 13:08:12 +00001096 LangOpts.Bool = 1;
1097 LangOpts.ObjC1 = 1;
1098 LangOpts.ObjC2 = 1;
1099 return LangOpts;
1100}
1101
Daniel Jasper8d1832e2013-01-07 13:26:07 +00001102} // namespace format
1103} // namespace clang