xref: /llvm-project/clang/lib/Format/Format.cpp (revision 55881d5def969c9e41fca87b51018d470340a888)
1 //===--- Format.cpp - Format C++ code -------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// This file implements functions declared in Format.h. This will be
11 /// split into separate files as we go.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #include "clang/Format/Format.h"
16 #include "AffectedRangeManager.h"
17 #include "ContinuationIndenter.h"
18 #include "FormatInternal.h"
19 #include "FormatTokenLexer.h"
20 #include "NamespaceEndCommentsFixer.h"
21 #include "SortJavaScriptImports.h"
22 #include "TokenAnalyzer.h"
23 #include "TokenAnnotator.h"
24 #include "UnwrappedLineFormatter.h"
25 #include "UnwrappedLineParser.h"
26 #include "UsingDeclarationsSorter.h"
27 #include "WhitespaceManager.h"
28 #include "clang/Basic/Diagnostic.h"
29 #include "clang/Basic/DiagnosticOptions.h"
30 #include "clang/Basic/SourceManager.h"
31 #include "clang/Lex/Lexer.h"
32 #include "clang/Tooling/Inclusions/HeaderIncludes.h"
33 #include "llvm/ADT/STLExtras.h"
34 #include "llvm/ADT/StringRef.h"
35 #include "llvm/Support/Allocator.h"
36 #include "llvm/Support/Debug.h"
37 #include "llvm/Support/Path.h"
38 #include "llvm/Support/Regex.h"
39 #include "llvm/Support/VirtualFileSystem.h"
40 #include "llvm/Support/YAMLTraits.h"
41 #include <algorithm>
42 #include <memory>
43 #include <mutex>
44 #include <string>
45 #include <unordered_map>
46 
47 #define DEBUG_TYPE "format-formatter"
48 
49 using clang::format::FormatStyle;
50 
51 LLVM_YAML_IS_SEQUENCE_VECTOR(clang::format::FormatStyle::RawStringFormat)
52 
53 namespace llvm {
54 namespace yaml {
55 template <> struct ScalarEnumerationTraits<FormatStyle::LanguageKind> {
56   static void enumeration(IO &IO, FormatStyle::LanguageKind &Value) {
57     IO.enumCase(Value, "Cpp", FormatStyle::LK_Cpp);
58     IO.enumCase(Value, "Java", FormatStyle::LK_Java);
59     IO.enumCase(Value, "JavaScript", FormatStyle::LK_JavaScript);
60     IO.enumCase(Value, "ObjC", FormatStyle::LK_ObjC);
61     IO.enumCase(Value, "Proto", FormatStyle::LK_Proto);
62     IO.enumCase(Value, "TableGen", FormatStyle::LK_TableGen);
63     IO.enumCase(Value, "TextProto", FormatStyle::LK_TextProto);
64   }
65 };
66 
67 template <> struct ScalarEnumerationTraits<FormatStyle::LanguageStandard> {
68   static void enumeration(IO &IO, FormatStyle::LanguageStandard &Value) {
69     IO.enumCase(Value, "Cpp03", FormatStyle::LS_Cpp03);
70     IO.enumCase(Value, "C++03", FormatStyle::LS_Cpp03);
71     IO.enumCase(Value, "Cpp11", FormatStyle::LS_Cpp11);
72     IO.enumCase(Value, "C++11", FormatStyle::LS_Cpp11);
73     IO.enumCase(Value, "Auto", FormatStyle::LS_Auto);
74   }
75 };
76 
77 template <> struct ScalarEnumerationTraits<FormatStyle::UseTabStyle> {
78   static void enumeration(IO &IO, FormatStyle::UseTabStyle &Value) {
79     IO.enumCase(Value, "Never", FormatStyle::UT_Never);
80     IO.enumCase(Value, "false", FormatStyle::UT_Never);
81     IO.enumCase(Value, "Always", FormatStyle::UT_Always);
82     IO.enumCase(Value, "true", FormatStyle::UT_Always);
83     IO.enumCase(Value, "ForIndentation", FormatStyle::UT_ForIndentation);
84     IO.enumCase(Value, "ForContinuationAndIndentation",
85                 FormatStyle::UT_ForContinuationAndIndentation);
86   }
87 };
88 
89 template <> struct ScalarEnumerationTraits<FormatStyle::JavaScriptQuoteStyle> {
90   static void enumeration(IO &IO, FormatStyle::JavaScriptQuoteStyle &Value) {
91     IO.enumCase(Value, "Leave", FormatStyle::JSQS_Leave);
92     IO.enumCase(Value, "Single", FormatStyle::JSQS_Single);
93     IO.enumCase(Value, "Double", FormatStyle::JSQS_Double);
94   }
95 };
96 
97 template <> struct ScalarEnumerationTraits<FormatStyle::ShortFunctionStyle> {
98   static void enumeration(IO &IO, FormatStyle::ShortFunctionStyle &Value) {
99     IO.enumCase(Value, "None", FormatStyle::SFS_None);
100     IO.enumCase(Value, "false", FormatStyle::SFS_None);
101     IO.enumCase(Value, "All", FormatStyle::SFS_All);
102     IO.enumCase(Value, "true", FormatStyle::SFS_All);
103     IO.enumCase(Value, "Inline", FormatStyle::SFS_Inline);
104     IO.enumCase(Value, "InlineOnly", FormatStyle::SFS_InlineOnly);
105     IO.enumCase(Value, "Empty", FormatStyle::SFS_Empty);
106   }
107 };
108 
109 template <> struct ScalarEnumerationTraits<FormatStyle::ShortIfStyle> {
110   static void enumeration(IO &IO, FormatStyle::ShortIfStyle &Value) {
111     IO.enumCase(Value, "Never", FormatStyle::SIS_Never);
112     IO.enumCase(Value, "Always", FormatStyle::SIS_Always);
113     IO.enumCase(Value, "WithoutElse", FormatStyle::SIS_WithoutElse);
114 
115     // For backward compatibility.
116     IO.enumCase(Value, "false", FormatStyle::SIS_Never);
117     IO.enumCase(Value, "true", FormatStyle::SIS_WithoutElse);
118   }
119 };
120 
121 template <> struct ScalarEnumerationTraits<FormatStyle::BinPackStyle> {
122   static void enumeration(IO &IO, FormatStyle::BinPackStyle &Value) {
123     IO.enumCase(Value, "Auto", FormatStyle::BPS_Auto);
124     IO.enumCase(Value, "Always", FormatStyle::BPS_Always);
125     IO.enumCase(Value, "Never", FormatStyle::BPS_Never);
126   }
127 };
128 
129 template <> struct ScalarEnumerationTraits<FormatStyle::BinaryOperatorStyle> {
130   static void enumeration(IO &IO, FormatStyle::BinaryOperatorStyle &Value) {
131     IO.enumCase(Value, "All", FormatStyle::BOS_All);
132     IO.enumCase(Value, "true", FormatStyle::BOS_All);
133     IO.enumCase(Value, "None", FormatStyle::BOS_None);
134     IO.enumCase(Value, "false", FormatStyle::BOS_None);
135     IO.enumCase(Value, "NonAssignment", FormatStyle::BOS_NonAssignment);
136   }
137 };
138 
139 template <> struct ScalarEnumerationTraits<FormatStyle::BraceBreakingStyle> {
140   static void enumeration(IO &IO, FormatStyle::BraceBreakingStyle &Value) {
141     IO.enumCase(Value, "Attach", FormatStyle::BS_Attach);
142     IO.enumCase(Value, "Linux", FormatStyle::BS_Linux);
143     IO.enumCase(Value, "Mozilla", FormatStyle::BS_Mozilla);
144     IO.enumCase(Value, "Stroustrup", FormatStyle::BS_Stroustrup);
145     IO.enumCase(Value, "Allman", FormatStyle::BS_Allman);
146     IO.enumCase(Value, "GNU", FormatStyle::BS_GNU);
147     IO.enumCase(Value, "WebKit", FormatStyle::BS_WebKit);
148     IO.enumCase(Value, "Custom", FormatStyle::BS_Custom);
149   }
150 };
151 
152 template <>
153 struct ScalarEnumerationTraits<FormatStyle::BreakConstructorInitializersStyle> {
154   static void
155   enumeration(IO &IO, FormatStyle::BreakConstructorInitializersStyle &Value) {
156     IO.enumCase(Value, "BeforeColon", FormatStyle::BCIS_BeforeColon);
157     IO.enumCase(Value, "BeforeComma", FormatStyle::BCIS_BeforeComma);
158     IO.enumCase(Value, "AfterColon", FormatStyle::BCIS_AfterColon);
159   }
160 };
161 
162 template <>
163 struct ScalarEnumerationTraits<FormatStyle::BreakInheritanceListStyle> {
164   static void enumeration(IO &IO,
165                           FormatStyle::BreakInheritanceListStyle &Value) {
166     IO.enumCase(Value, "BeforeColon", FormatStyle::BILS_BeforeColon);
167     IO.enumCase(Value, "BeforeComma", FormatStyle::BILS_BeforeComma);
168     IO.enumCase(Value, "AfterColon", FormatStyle::BILS_AfterColon);
169   }
170 };
171 
172 template <>
173 struct ScalarEnumerationTraits<FormatStyle::PPDirectiveIndentStyle> {
174   static void enumeration(IO &IO, FormatStyle::PPDirectiveIndentStyle &Value) {
175     IO.enumCase(Value, "None", FormatStyle::PPDIS_None);
176     IO.enumCase(Value, "AfterHash", FormatStyle::PPDIS_AfterHash);
177   }
178 };
179 
180 template <>
181 struct ScalarEnumerationTraits<FormatStyle::ReturnTypeBreakingStyle> {
182   static void enumeration(IO &IO, FormatStyle::ReturnTypeBreakingStyle &Value) {
183     IO.enumCase(Value, "None", FormatStyle::RTBS_None);
184     IO.enumCase(Value, "All", FormatStyle::RTBS_All);
185     IO.enumCase(Value, "TopLevel", FormatStyle::RTBS_TopLevel);
186     IO.enumCase(Value, "TopLevelDefinitions",
187                 FormatStyle::RTBS_TopLevelDefinitions);
188     IO.enumCase(Value, "AllDefinitions", FormatStyle::RTBS_AllDefinitions);
189   }
190 };
191 
192 template <>
193 struct ScalarEnumerationTraits<FormatStyle::BreakTemplateDeclarationsStyle> {
194   static void enumeration(IO &IO,
195                           FormatStyle::BreakTemplateDeclarationsStyle &Value) {
196     IO.enumCase(Value, "No", FormatStyle::BTDS_No);
197     IO.enumCase(Value, "MultiLine", FormatStyle::BTDS_MultiLine);
198     IO.enumCase(Value, "Yes", FormatStyle::BTDS_Yes);
199 
200     // For backward compatibility.
201     IO.enumCase(Value, "false", FormatStyle::BTDS_MultiLine);
202     IO.enumCase(Value, "true", FormatStyle::BTDS_Yes);
203   }
204 };
205 
206 template <>
207 struct ScalarEnumerationTraits<FormatStyle::DefinitionReturnTypeBreakingStyle> {
208   static void
209   enumeration(IO &IO, FormatStyle::DefinitionReturnTypeBreakingStyle &Value) {
210     IO.enumCase(Value, "None", FormatStyle::DRTBS_None);
211     IO.enumCase(Value, "All", FormatStyle::DRTBS_All);
212     IO.enumCase(Value, "TopLevel", FormatStyle::DRTBS_TopLevel);
213 
214     // For backward compatibility.
215     IO.enumCase(Value, "false", FormatStyle::DRTBS_None);
216     IO.enumCase(Value, "true", FormatStyle::DRTBS_All);
217   }
218 };
219 
220 template <>
221 struct ScalarEnumerationTraits<FormatStyle::NamespaceIndentationKind> {
222   static void enumeration(IO &IO,
223                           FormatStyle::NamespaceIndentationKind &Value) {
224     IO.enumCase(Value, "None", FormatStyle::NI_None);
225     IO.enumCase(Value, "Inner", FormatStyle::NI_Inner);
226     IO.enumCase(Value, "All", FormatStyle::NI_All);
227   }
228 };
229 
230 template <> struct ScalarEnumerationTraits<FormatStyle::BracketAlignmentStyle> {
231   static void enumeration(IO &IO, FormatStyle::BracketAlignmentStyle &Value) {
232     IO.enumCase(Value, "Align", FormatStyle::BAS_Align);
233     IO.enumCase(Value, "DontAlign", FormatStyle::BAS_DontAlign);
234     IO.enumCase(Value, "AlwaysBreak", FormatStyle::BAS_AlwaysBreak);
235 
236     // For backward compatibility.
237     IO.enumCase(Value, "true", FormatStyle::BAS_Align);
238     IO.enumCase(Value, "false", FormatStyle::BAS_DontAlign);
239   }
240 };
241 
242 template <>
243 struct ScalarEnumerationTraits<FormatStyle::EscapedNewlineAlignmentStyle> {
244   static void enumeration(IO &IO,
245                           FormatStyle::EscapedNewlineAlignmentStyle &Value) {
246     IO.enumCase(Value, "DontAlign", FormatStyle::ENAS_DontAlign);
247     IO.enumCase(Value, "Left", FormatStyle::ENAS_Left);
248     IO.enumCase(Value, "Right", FormatStyle::ENAS_Right);
249 
250     // For backward compatibility.
251     IO.enumCase(Value, "true", FormatStyle::ENAS_Left);
252     IO.enumCase(Value, "false", FormatStyle::ENAS_Right);
253   }
254 };
255 
256 template <> struct ScalarEnumerationTraits<FormatStyle::PointerAlignmentStyle> {
257   static void enumeration(IO &IO, FormatStyle::PointerAlignmentStyle &Value) {
258     IO.enumCase(Value, "Middle", FormatStyle::PAS_Middle);
259     IO.enumCase(Value, "Left", FormatStyle::PAS_Left);
260     IO.enumCase(Value, "Right", FormatStyle::PAS_Right);
261 
262     // For backward compatibility.
263     IO.enumCase(Value, "true", FormatStyle::PAS_Left);
264     IO.enumCase(Value, "false", FormatStyle::PAS_Right);
265   }
266 };
267 
268 template <>
269 struct ScalarEnumerationTraits<FormatStyle::SpaceBeforeParensOptions> {
270   static void enumeration(IO &IO,
271                           FormatStyle::SpaceBeforeParensOptions &Value) {
272     IO.enumCase(Value, "Never", FormatStyle::SBPO_Never);
273     IO.enumCase(Value, "ControlStatements",
274                 FormatStyle::SBPO_ControlStatements);
275     IO.enumCase(Value, "Always", FormatStyle::SBPO_Always);
276 
277     // For backward compatibility.
278     IO.enumCase(Value, "false", FormatStyle::SBPO_Never);
279     IO.enumCase(Value, "true", FormatStyle::SBPO_ControlStatements);
280   }
281 };
282 
283 template <> struct MappingTraits<FormatStyle> {
284   static void mapping(IO &IO, FormatStyle &Style) {
285     // When reading, read the language first, we need it for getPredefinedStyle.
286     IO.mapOptional("Language", Style.Language);
287 
288     if (IO.outputting()) {
289       StringRef StylesArray[] = {"LLVM",    "Google", "Chromium",
290                                  "Mozilla", "WebKit", "GNU"};
291       ArrayRef<StringRef> Styles(StylesArray);
292       for (size_t i = 0, e = Styles.size(); i < e; ++i) {
293         StringRef StyleName(Styles[i]);
294         FormatStyle PredefinedStyle;
295         if (getPredefinedStyle(StyleName, Style.Language, &PredefinedStyle) &&
296             Style == PredefinedStyle) {
297           IO.mapOptional("# BasedOnStyle", StyleName);
298           break;
299         }
300       }
301     } else {
302       StringRef BasedOnStyle;
303       IO.mapOptional("BasedOnStyle", BasedOnStyle);
304       if (!BasedOnStyle.empty()) {
305         FormatStyle::LanguageKind OldLanguage = Style.Language;
306         FormatStyle::LanguageKind Language =
307             ((FormatStyle *)IO.getContext())->Language;
308         if (!getPredefinedStyle(BasedOnStyle, Language, &Style)) {
309           IO.setError(Twine("Unknown value for BasedOnStyle: ", BasedOnStyle));
310           return;
311         }
312         Style.Language = OldLanguage;
313       }
314     }
315 
316     // For backward compatibility.
317     if (!IO.outputting()) {
318       IO.mapOptional("AlignEscapedNewlinesLeft", Style.AlignEscapedNewlines);
319       IO.mapOptional("DerivePointerBinding", Style.DerivePointerAlignment);
320       IO.mapOptional("IndentFunctionDeclarationAfterType",
321                      Style.IndentWrappedFunctionNames);
322       IO.mapOptional("PointerBindsToType", Style.PointerAlignment);
323       IO.mapOptional("SpaceAfterControlStatementKeyword",
324                      Style.SpaceBeforeParens);
325     }
326 
327     IO.mapOptional("AccessModifierOffset", Style.AccessModifierOffset);
328     IO.mapOptional("AlignAfterOpenBracket", Style.AlignAfterOpenBracket);
329     IO.mapOptional("AlignConsecutiveAssignments",
330                    Style.AlignConsecutiveAssignments);
331     IO.mapOptional("AlignConsecutiveDeclarations",
332                    Style.AlignConsecutiveDeclarations);
333     IO.mapOptional("AlignEscapedNewlines", Style.AlignEscapedNewlines);
334     IO.mapOptional("AlignOperands", Style.AlignOperands);
335     IO.mapOptional("AlignTrailingComments", Style.AlignTrailingComments);
336     IO.mapOptional("AllowAllParametersOfDeclarationOnNextLine",
337                    Style.AllowAllParametersOfDeclarationOnNextLine);
338     IO.mapOptional("AllowShortBlocksOnASingleLine",
339                    Style.AllowShortBlocksOnASingleLine);
340     IO.mapOptional("AllowShortCaseLabelsOnASingleLine",
341                    Style.AllowShortCaseLabelsOnASingleLine);
342     IO.mapOptional("AllowShortFunctionsOnASingleLine",
343                    Style.AllowShortFunctionsOnASingleLine);
344     IO.mapOptional("AllowShortIfStatementsOnASingleLine",
345                    Style.AllowShortIfStatementsOnASingleLine);
346     IO.mapOptional("AllowShortLoopsOnASingleLine",
347                    Style.AllowShortLoopsOnASingleLine);
348     IO.mapOptional("AlwaysBreakAfterDefinitionReturnType",
349                    Style.AlwaysBreakAfterDefinitionReturnType);
350     IO.mapOptional("AlwaysBreakAfterReturnType",
351                    Style.AlwaysBreakAfterReturnType);
352     // If AlwaysBreakAfterDefinitionReturnType was specified but
353     // AlwaysBreakAfterReturnType was not, initialize the latter from the
354     // former for backwards compatibility.
355     if (Style.AlwaysBreakAfterDefinitionReturnType != FormatStyle::DRTBS_None &&
356         Style.AlwaysBreakAfterReturnType == FormatStyle::RTBS_None) {
357       if (Style.AlwaysBreakAfterDefinitionReturnType == FormatStyle::DRTBS_All)
358         Style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_AllDefinitions;
359       else if (Style.AlwaysBreakAfterDefinitionReturnType ==
360                FormatStyle::DRTBS_TopLevel)
361         Style.AlwaysBreakAfterReturnType =
362             FormatStyle::RTBS_TopLevelDefinitions;
363     }
364 
365     IO.mapOptional("AlwaysBreakBeforeMultilineStrings",
366                    Style.AlwaysBreakBeforeMultilineStrings);
367     IO.mapOptional("AlwaysBreakTemplateDeclarations",
368                    Style.AlwaysBreakTemplateDeclarations);
369     IO.mapOptional("BinPackArguments", Style.BinPackArguments);
370     IO.mapOptional("BinPackParameters", Style.BinPackParameters);
371     IO.mapOptional("BraceWrapping", Style.BraceWrapping);
372     IO.mapOptional("BreakBeforeBinaryOperators",
373                    Style.BreakBeforeBinaryOperators);
374     IO.mapOptional("BreakBeforeBraces", Style.BreakBeforeBraces);
375 
376     bool BreakBeforeInheritanceComma = false;
377     IO.mapOptional("BreakBeforeInheritanceComma", BreakBeforeInheritanceComma);
378     IO.mapOptional("BreakInheritanceList", Style.BreakInheritanceList);
379     // If BreakBeforeInheritanceComma was specified but
380     // BreakInheritance was not, initialize the latter from the
381     // former for backwards compatibility.
382     if (BreakBeforeInheritanceComma &&
383         Style.BreakInheritanceList == FormatStyle::BILS_BeforeColon)
384       Style.BreakInheritanceList = FormatStyle::BILS_BeforeComma;
385 
386     IO.mapOptional("BreakBeforeTernaryOperators",
387                    Style.BreakBeforeTernaryOperators);
388 
389     bool BreakConstructorInitializersBeforeComma = false;
390     IO.mapOptional("BreakConstructorInitializersBeforeComma",
391                    BreakConstructorInitializersBeforeComma);
392     IO.mapOptional("BreakConstructorInitializers",
393                    Style.BreakConstructorInitializers);
394     // If BreakConstructorInitializersBeforeComma was specified but
395     // BreakConstructorInitializers was not, initialize the latter from the
396     // former for backwards compatibility.
397     if (BreakConstructorInitializersBeforeComma &&
398         Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeColon)
399       Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma;
400 
401     IO.mapOptional("BreakAfterJavaFieldAnnotations",
402                    Style.BreakAfterJavaFieldAnnotations);
403     IO.mapOptional("BreakStringLiterals", Style.BreakStringLiterals);
404     IO.mapOptional("ColumnLimit", Style.ColumnLimit);
405     IO.mapOptional("CommentPragmas", Style.CommentPragmas);
406     IO.mapOptional("CompactNamespaces", Style.CompactNamespaces);
407     IO.mapOptional("ConstructorInitializerAllOnOneLineOrOnePerLine",
408                    Style.ConstructorInitializerAllOnOneLineOrOnePerLine);
409     IO.mapOptional("ConstructorInitializerIndentWidth",
410                    Style.ConstructorInitializerIndentWidth);
411     IO.mapOptional("ContinuationIndentWidth", Style.ContinuationIndentWidth);
412     IO.mapOptional("Cpp11BracedListStyle", Style.Cpp11BracedListStyle);
413     IO.mapOptional("DerivePointerAlignment", Style.DerivePointerAlignment);
414     IO.mapOptional("DisableFormat", Style.DisableFormat);
415     IO.mapOptional("ExperimentalAutoDetectBinPacking",
416                    Style.ExperimentalAutoDetectBinPacking);
417     IO.mapOptional("FixNamespaceComments", Style.FixNamespaceComments);
418     IO.mapOptional("ForEachMacros", Style.ForEachMacros);
419     IO.mapOptional("IncludeBlocks", Style.IncludeStyle.IncludeBlocks);
420     IO.mapOptional("IncludeCategories", Style.IncludeStyle.IncludeCategories);
421     IO.mapOptional("IncludeIsMainRegex", Style.IncludeStyle.IncludeIsMainRegex);
422     IO.mapOptional("IndentCaseLabels", Style.IndentCaseLabels);
423     IO.mapOptional("IndentPPDirectives", Style.IndentPPDirectives);
424     IO.mapOptional("IndentWidth", Style.IndentWidth);
425     IO.mapOptional("IndentWrappedFunctionNames",
426                    Style.IndentWrappedFunctionNames);
427     IO.mapOptional("JavaImportGroups", Style.JavaImportGroups);
428     IO.mapOptional("JavaScriptQuotes", Style.JavaScriptQuotes);
429     IO.mapOptional("JavaScriptWrapImports", Style.JavaScriptWrapImports);
430     IO.mapOptional("KeepEmptyLinesAtTheStartOfBlocks",
431                    Style.KeepEmptyLinesAtTheStartOfBlocks);
432     IO.mapOptional("MacroBlockBegin", Style.MacroBlockBegin);
433     IO.mapOptional("MacroBlockEnd", Style.MacroBlockEnd);
434     IO.mapOptional("MaxEmptyLinesToKeep", Style.MaxEmptyLinesToKeep);
435     IO.mapOptional("NamespaceIndentation", Style.NamespaceIndentation);
436     IO.mapOptional("ObjCBinPackProtocolList", Style.ObjCBinPackProtocolList);
437     IO.mapOptional("ObjCBlockIndentWidth", Style.ObjCBlockIndentWidth);
438     IO.mapOptional("ObjCSpaceAfterProperty", Style.ObjCSpaceAfterProperty);
439     IO.mapOptional("ObjCSpaceBeforeProtocolList",
440                    Style.ObjCSpaceBeforeProtocolList);
441     IO.mapOptional("PenaltyBreakAssignment", Style.PenaltyBreakAssignment);
442     IO.mapOptional("PenaltyBreakBeforeFirstCallParameter",
443                    Style.PenaltyBreakBeforeFirstCallParameter);
444     IO.mapOptional("PenaltyBreakComment", Style.PenaltyBreakComment);
445     IO.mapOptional("PenaltyBreakFirstLessLess",
446                    Style.PenaltyBreakFirstLessLess);
447     IO.mapOptional("PenaltyBreakString", Style.PenaltyBreakString);
448     IO.mapOptional("PenaltyBreakTemplateDeclaration",
449                    Style.PenaltyBreakTemplateDeclaration);
450     IO.mapOptional("PenaltyExcessCharacter", Style.PenaltyExcessCharacter);
451     IO.mapOptional("PenaltyReturnTypeOnItsOwnLine",
452                    Style.PenaltyReturnTypeOnItsOwnLine);
453     IO.mapOptional("PointerAlignment", Style.PointerAlignment);
454     IO.mapOptional("RawStringFormats", Style.RawStringFormats);
455     IO.mapOptional("ReflowComments", Style.ReflowComments);
456     IO.mapOptional("SortIncludes", Style.SortIncludes);
457     IO.mapOptional("SortUsingDeclarations", Style.SortUsingDeclarations);
458     IO.mapOptional("SpaceAfterCStyleCast", Style.SpaceAfterCStyleCast);
459     IO.mapOptional("SpaceAfterTemplateKeyword",
460                    Style.SpaceAfterTemplateKeyword);
461     IO.mapOptional("SpaceBeforeAssignmentOperators",
462                    Style.SpaceBeforeAssignmentOperators);
463     IO.mapOptional("SpaceBeforeCpp11BracedList",
464                    Style.SpaceBeforeCpp11BracedList);
465     IO.mapOptional("SpaceBeforeCtorInitializerColon",
466                    Style.SpaceBeforeCtorInitializerColon);
467     IO.mapOptional("SpaceBeforeInheritanceColon",
468                    Style.SpaceBeforeInheritanceColon);
469     IO.mapOptional("SpaceBeforeParens", Style.SpaceBeforeParens);
470     IO.mapOptional("SpaceBeforeRangeBasedForLoopColon",
471                    Style.SpaceBeforeRangeBasedForLoopColon);
472     IO.mapOptional("SpaceInEmptyParentheses", Style.SpaceInEmptyParentheses);
473     IO.mapOptional("SpacesBeforeTrailingComments",
474                    Style.SpacesBeforeTrailingComments);
475     IO.mapOptional("SpacesInAngles", Style.SpacesInAngles);
476     IO.mapOptional("SpacesInContainerLiterals",
477                    Style.SpacesInContainerLiterals);
478     IO.mapOptional("SpacesInCStyleCastParentheses",
479                    Style.SpacesInCStyleCastParentheses);
480     IO.mapOptional("SpacesInParentheses", Style.SpacesInParentheses);
481     IO.mapOptional("SpacesInSquareBrackets", Style.SpacesInSquareBrackets);
482     IO.mapOptional("Standard", Style.Standard);
483     IO.mapOptional("StatementMacros", Style.StatementMacros);
484     IO.mapOptional("TabWidth", Style.TabWidth);
485     IO.mapOptional("UseTab", Style.UseTab);
486   }
487 };
488 
489 template <> struct MappingTraits<FormatStyle::BraceWrappingFlags> {
490   static void mapping(IO &IO, FormatStyle::BraceWrappingFlags &Wrapping) {
491     IO.mapOptional("AfterClass", Wrapping.AfterClass);
492     IO.mapOptional("AfterControlStatement", Wrapping.AfterControlStatement);
493     IO.mapOptional("AfterEnum", Wrapping.AfterEnum);
494     IO.mapOptional("AfterFunction", Wrapping.AfterFunction);
495     IO.mapOptional("AfterNamespace", Wrapping.AfterNamespace);
496     IO.mapOptional("AfterObjCDeclaration", Wrapping.AfterObjCDeclaration);
497     IO.mapOptional("AfterStruct", Wrapping.AfterStruct);
498     IO.mapOptional("AfterUnion", Wrapping.AfterUnion);
499     IO.mapOptional("AfterExternBlock", Wrapping.AfterExternBlock);
500     IO.mapOptional("BeforeCatch", Wrapping.BeforeCatch);
501     IO.mapOptional("BeforeElse", Wrapping.BeforeElse);
502     IO.mapOptional("IndentBraces", Wrapping.IndentBraces);
503     IO.mapOptional("SplitEmptyFunction", Wrapping.SplitEmptyFunction);
504     IO.mapOptional("SplitEmptyRecord", Wrapping.SplitEmptyRecord);
505     IO.mapOptional("SplitEmptyNamespace", Wrapping.SplitEmptyNamespace);
506   }
507 };
508 
509 template <> struct MappingTraits<FormatStyle::RawStringFormat> {
510   static void mapping(IO &IO, FormatStyle::RawStringFormat &Format) {
511     IO.mapOptional("Language", Format.Language);
512     IO.mapOptional("Delimiters", Format.Delimiters);
513     IO.mapOptional("EnclosingFunctions", Format.EnclosingFunctions);
514     IO.mapOptional("CanonicalDelimiter", Format.CanonicalDelimiter);
515     IO.mapOptional("BasedOnStyle", Format.BasedOnStyle);
516   }
517 };
518 
519 // Allows to read vector<FormatStyle> while keeping default values.
520 // IO.getContext() should contain a pointer to the FormatStyle structure, that
521 // will be used to get default values for missing keys.
522 // If the first element has no Language specified, it will be treated as the
523 // default one for the following elements.
524 template <> struct DocumentListTraits<std::vector<FormatStyle>> {
525   static size_t size(IO &IO, std::vector<FormatStyle> &Seq) {
526     return Seq.size();
527   }
528   static FormatStyle &element(IO &IO, std::vector<FormatStyle> &Seq,
529                               size_t Index) {
530     if (Index >= Seq.size()) {
531       assert(Index == Seq.size());
532       FormatStyle Template;
533       if (!Seq.empty() && Seq[0].Language == FormatStyle::LK_None) {
534         Template = Seq[0];
535       } else {
536         Template = *((const FormatStyle *)IO.getContext());
537         Template.Language = FormatStyle::LK_None;
538       }
539       Seq.resize(Index + 1, Template);
540     }
541     return Seq[Index];
542   }
543 };
544 } // namespace yaml
545 } // namespace llvm
546 
547 namespace clang {
548 namespace format {
549 
550 const std::error_category &getParseCategory() {
551   static const ParseErrorCategory C{};
552   return C;
553 }
554 std::error_code make_error_code(ParseError e) {
555   return std::error_code(static_cast<int>(e), getParseCategory());
556 }
557 
558 inline llvm::Error make_string_error(const llvm::Twine &Message) {
559   return llvm::make_error<llvm::StringError>(Message,
560                                              llvm::inconvertibleErrorCode());
561 }
562 
563 const char *ParseErrorCategory::name() const noexcept {
564   return "clang-format.parse_error";
565 }
566 
567 std::string ParseErrorCategory::message(int EV) const {
568   switch (static_cast<ParseError>(EV)) {
569   case ParseError::Success:
570     return "Success";
571   case ParseError::Error:
572     return "Invalid argument";
573   case ParseError::Unsuitable:
574     return "Unsuitable";
575   }
576   llvm_unreachable("unexpected parse error");
577 }
578 
579 static FormatStyle expandPresets(const FormatStyle &Style) {
580   if (Style.BreakBeforeBraces == FormatStyle::BS_Custom)
581     return Style;
582   FormatStyle Expanded = Style;
583   Expanded.BraceWrapping = {false, false, false, false, false,
584                             false, false, false, false, false,
585                             false, false, true,  true,  true};
586   switch (Style.BreakBeforeBraces) {
587   case FormatStyle::BS_Linux:
588     Expanded.BraceWrapping.AfterClass = true;
589     Expanded.BraceWrapping.AfterFunction = true;
590     Expanded.BraceWrapping.AfterNamespace = true;
591     break;
592   case FormatStyle::BS_Mozilla:
593     Expanded.BraceWrapping.AfterClass = true;
594     Expanded.BraceWrapping.AfterEnum = true;
595     Expanded.BraceWrapping.AfterFunction = true;
596     Expanded.BraceWrapping.AfterStruct = true;
597     Expanded.BraceWrapping.AfterUnion = true;
598     Expanded.BraceWrapping.AfterExternBlock = true;
599     Expanded.BraceWrapping.SplitEmptyFunction = true;
600     Expanded.BraceWrapping.SplitEmptyRecord = false;
601     break;
602   case FormatStyle::BS_Stroustrup:
603     Expanded.BraceWrapping.AfterFunction = true;
604     Expanded.BraceWrapping.BeforeCatch = true;
605     Expanded.BraceWrapping.BeforeElse = true;
606     break;
607   case FormatStyle::BS_Allman:
608     Expanded.BraceWrapping.AfterClass = true;
609     Expanded.BraceWrapping.AfterControlStatement = true;
610     Expanded.BraceWrapping.AfterEnum = true;
611     Expanded.BraceWrapping.AfterFunction = true;
612     Expanded.BraceWrapping.AfterNamespace = true;
613     Expanded.BraceWrapping.AfterObjCDeclaration = true;
614     Expanded.BraceWrapping.AfterStruct = true;
615     Expanded.BraceWrapping.AfterExternBlock = true;
616     Expanded.BraceWrapping.BeforeCatch = true;
617     Expanded.BraceWrapping.BeforeElse = true;
618     break;
619   case FormatStyle::BS_GNU:
620     Expanded.BraceWrapping = {true, true, true, true, true, true, true, true,
621                               true, true, true, true, true, true, true};
622     break;
623   case FormatStyle::BS_WebKit:
624     Expanded.BraceWrapping.AfterFunction = true;
625     break;
626   default:
627     break;
628   }
629   return Expanded;
630 }
631 
632 FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
633   FormatStyle LLVMStyle;
634   LLVMStyle.Language = Language;
635   LLVMStyle.AccessModifierOffset = -2;
636   LLVMStyle.AlignEscapedNewlines = FormatStyle::ENAS_Right;
637   LLVMStyle.AlignAfterOpenBracket = FormatStyle::BAS_Align;
638   LLVMStyle.AlignOperands = true;
639   LLVMStyle.AlignTrailingComments = true;
640   LLVMStyle.AlignConsecutiveAssignments = false;
641   LLVMStyle.AlignConsecutiveDeclarations = false;
642   LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true;
643   LLVMStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
644   LLVMStyle.AllowShortBlocksOnASingleLine = false;
645   LLVMStyle.AllowShortCaseLabelsOnASingleLine = false;
646   LLVMStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
647   LLVMStyle.AllowShortLoopsOnASingleLine = false;
648   LLVMStyle.AlwaysBreakAfterReturnType = FormatStyle::RTBS_None;
649   LLVMStyle.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_None;
650   LLVMStyle.AlwaysBreakBeforeMultilineStrings = false;
651   LLVMStyle.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_MultiLine;
652   LLVMStyle.BinPackArguments = true;
653   LLVMStyle.BinPackParameters = true;
654   LLVMStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_None;
655   LLVMStyle.BreakBeforeTernaryOperators = true;
656   LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach;
657   LLVMStyle.BraceWrapping = {false, false, false, false, false,
658                              false, false, false, false, false,
659                              false, false, true,  true,  true};
660   LLVMStyle.BreakAfterJavaFieldAnnotations = false;
661   LLVMStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon;
662   LLVMStyle.BreakInheritanceList = FormatStyle::BILS_BeforeColon;
663   LLVMStyle.BreakStringLiterals = true;
664   LLVMStyle.ColumnLimit = 80;
665   LLVMStyle.CommentPragmas = "^ IWYU pragma:";
666   LLVMStyle.CompactNamespaces = false;
667   LLVMStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = false;
668   LLVMStyle.ConstructorInitializerIndentWidth = 4;
669   LLVMStyle.ContinuationIndentWidth = 4;
670   LLVMStyle.Cpp11BracedListStyle = true;
671   LLVMStyle.DerivePointerAlignment = false;
672   LLVMStyle.ExperimentalAutoDetectBinPacking = false;
673   LLVMStyle.FixNamespaceComments = true;
674   LLVMStyle.ForEachMacros.push_back("foreach");
675   LLVMStyle.ForEachMacros.push_back("Q_FOREACH");
676   LLVMStyle.ForEachMacros.push_back("BOOST_FOREACH");
677   LLVMStyle.IncludeStyle.IncludeCategories = {
678       {"^\"(llvm|llvm-c|clang|clang-c)/", 2},
679       {"^(<|\"(gtest|gmock|isl|json)/)", 3},
680       {".*", 1}};
681   LLVMStyle.IncludeStyle.IncludeIsMainRegex = "(Test)?$";
682   LLVMStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Preserve;
683   LLVMStyle.IndentCaseLabels = false;
684   LLVMStyle.IndentPPDirectives = FormatStyle::PPDIS_None;
685   LLVMStyle.IndentWrappedFunctionNames = false;
686   LLVMStyle.IndentWidth = 2;
687   LLVMStyle.JavaScriptQuotes = FormatStyle::JSQS_Leave;
688   LLVMStyle.JavaScriptWrapImports = true;
689   LLVMStyle.TabWidth = 8;
690   LLVMStyle.MaxEmptyLinesToKeep = 1;
691   LLVMStyle.KeepEmptyLinesAtTheStartOfBlocks = true;
692   LLVMStyle.NamespaceIndentation = FormatStyle::NI_None;
693   LLVMStyle.ObjCBinPackProtocolList = FormatStyle::BPS_Auto;
694   LLVMStyle.ObjCBlockIndentWidth = 2;
695   LLVMStyle.ObjCSpaceAfterProperty = false;
696   LLVMStyle.ObjCSpaceBeforeProtocolList = true;
697   LLVMStyle.PointerAlignment = FormatStyle::PAS_Right;
698   LLVMStyle.SpacesBeforeTrailingComments = 1;
699   LLVMStyle.Standard = FormatStyle::LS_Cpp11;
700   LLVMStyle.UseTab = FormatStyle::UT_Never;
701   LLVMStyle.ReflowComments = true;
702   LLVMStyle.SpacesInParentheses = false;
703   LLVMStyle.SpacesInSquareBrackets = false;
704   LLVMStyle.SpaceInEmptyParentheses = false;
705   LLVMStyle.SpacesInContainerLiterals = true;
706   LLVMStyle.SpacesInCStyleCastParentheses = false;
707   LLVMStyle.SpaceAfterCStyleCast = false;
708   LLVMStyle.SpaceAfterTemplateKeyword = true;
709   LLVMStyle.SpaceBeforeCtorInitializerColon = true;
710   LLVMStyle.SpaceBeforeInheritanceColon = true;
711   LLVMStyle.SpaceBeforeParens = FormatStyle::SBPO_ControlStatements;
712   LLVMStyle.SpaceBeforeRangeBasedForLoopColon = true;
713   LLVMStyle.SpaceBeforeAssignmentOperators = true;
714   LLVMStyle.SpaceBeforeCpp11BracedList = false;
715   LLVMStyle.SpacesInAngles = false;
716 
717   LLVMStyle.PenaltyBreakAssignment = prec::Assignment;
718   LLVMStyle.PenaltyBreakComment = 300;
719   LLVMStyle.PenaltyBreakFirstLessLess = 120;
720   LLVMStyle.PenaltyBreakString = 1000;
721   LLVMStyle.PenaltyExcessCharacter = 1000000;
722   LLVMStyle.PenaltyReturnTypeOnItsOwnLine = 60;
723   LLVMStyle.PenaltyBreakBeforeFirstCallParameter = 19;
724   LLVMStyle.PenaltyBreakTemplateDeclaration = prec::Relational;
725 
726   LLVMStyle.DisableFormat = false;
727   LLVMStyle.SortIncludes = true;
728   LLVMStyle.SortUsingDeclarations = true;
729   LLVMStyle.StatementMacros.push_back("Q_UNUSED");
730   LLVMStyle.StatementMacros.push_back("QT_REQUIRE_VERSION");
731 
732   // Defaults that differ when not C++.
733   if (Language == FormatStyle::LK_TableGen) {
734     LLVMStyle.SpacesInContainerLiterals = false;
735   }
736 
737   return LLVMStyle;
738 }
739 
740 FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
741   if (Language == FormatStyle::LK_TextProto) {
742     FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_Proto);
743     GoogleStyle.Language = FormatStyle::LK_TextProto;
744 
745     return GoogleStyle;
746   }
747 
748   FormatStyle GoogleStyle = getLLVMStyle(Language);
749 
750   GoogleStyle.AccessModifierOffset = -1;
751   GoogleStyle.AlignEscapedNewlines = FormatStyle::ENAS_Left;
752   GoogleStyle.AllowShortIfStatementsOnASingleLine =
753       FormatStyle::SIS_WithoutElse;
754   GoogleStyle.AllowShortLoopsOnASingleLine = true;
755   GoogleStyle.AlwaysBreakBeforeMultilineStrings = true;
756   GoogleStyle.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_Yes;
757   GoogleStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = true;
758   GoogleStyle.DerivePointerAlignment = true;
759   GoogleStyle.IncludeStyle.IncludeCategories = {
760       {"^<ext/.*\\.h>", 2}, {"^<.*\\.h>", 1}, {"^<.*", 2}, {".*", 3}};
761   GoogleStyle.IncludeStyle.IncludeIsMainRegex = "([-_](test|unittest))?$";
762   GoogleStyle.IndentCaseLabels = true;
763   GoogleStyle.KeepEmptyLinesAtTheStartOfBlocks = false;
764   GoogleStyle.ObjCBinPackProtocolList = FormatStyle::BPS_Never;
765   GoogleStyle.ObjCSpaceAfterProperty = false;
766   GoogleStyle.ObjCSpaceBeforeProtocolList = true;
767   GoogleStyle.PointerAlignment = FormatStyle::PAS_Left;
768   GoogleStyle.RawStringFormats = {
769       {
770           FormatStyle::LK_Cpp,
771           /*Delimiters=*/
772           {
773               "cc",
774               "CC",
775               "cpp",
776               "Cpp",
777               "CPP",
778               "c++",
779               "C++",
780           },
781           /*EnclosingFunctionNames=*/
782           {},
783           /*CanonicalDelimiter=*/"",
784           /*BasedOnStyle=*/"google",
785       },
786       {
787           FormatStyle::LK_TextProto,
788           /*Delimiters=*/
789           {
790               "pb",
791               "PB",
792               "proto",
793               "PROTO",
794           },
795           /*EnclosingFunctionNames=*/
796           {
797               "EqualsProto",
798               "EquivToProto",
799               "PARSE_PARTIAL_TEXT_PROTO",
800               "PARSE_TEST_PROTO",
801               "PARSE_TEXT_PROTO",
802               "ParseTextOrDie",
803               "ParseTextProtoOrDie",
804           },
805           /*CanonicalDelimiter=*/"",
806           /*BasedOnStyle=*/"google",
807       },
808   };
809   GoogleStyle.SpacesBeforeTrailingComments = 2;
810   GoogleStyle.Standard = FormatStyle::LS_Auto;
811 
812   GoogleStyle.PenaltyReturnTypeOnItsOwnLine = 200;
813   GoogleStyle.PenaltyBreakBeforeFirstCallParameter = 1;
814 
815   if (Language == FormatStyle::LK_Java) {
816     GoogleStyle.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign;
817     GoogleStyle.AlignOperands = false;
818     GoogleStyle.AlignTrailingComments = false;
819     GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
820     GoogleStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
821     GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
822     GoogleStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment;
823     GoogleStyle.ColumnLimit = 100;
824     GoogleStyle.SpaceAfterCStyleCast = true;
825     GoogleStyle.SpacesBeforeTrailingComments = 1;
826   } else if (Language == FormatStyle::LK_JavaScript) {
827     GoogleStyle.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak;
828     GoogleStyle.AlignOperands = false;
829     GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
830     GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
831     GoogleStyle.BreakBeforeTernaryOperators = false;
832     // taze:, triple slash directives (`/// <...`), @see, which is commonly
833     // followed by overlong URLs.
834     GoogleStyle.CommentPragmas = "(taze:|^/[ \t]*<|@see)";
835     GoogleStyle.MaxEmptyLinesToKeep = 3;
836     GoogleStyle.NamespaceIndentation = FormatStyle::NI_All;
837     GoogleStyle.SpacesInContainerLiterals = false;
838     GoogleStyle.JavaScriptQuotes = FormatStyle::JSQS_Single;
839     GoogleStyle.JavaScriptWrapImports = false;
840   } else if (Language == FormatStyle::LK_Proto) {
841     GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
842     GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
843     GoogleStyle.SpacesInContainerLiterals = false;
844     GoogleStyle.Cpp11BracedListStyle = false;
845     // This affects protocol buffer options specifications and text protos.
846     // Text protos are currently mostly formatted inside C++ raw string literals
847     // and often the current breaking behavior of string literals is not
848     // beneficial there. Investigate turning this on once proper string reflow
849     // has been implemented.
850     GoogleStyle.BreakStringLiterals = false;
851   } else if (Language == FormatStyle::LK_ObjC) {
852     GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
853     GoogleStyle.ColumnLimit = 100;
854   }
855 
856   return GoogleStyle;
857 }
858 
859 FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language) {
860   FormatStyle ChromiumStyle = getGoogleStyle(Language);
861   if (Language == FormatStyle::LK_Java) {
862     ChromiumStyle.AllowShortIfStatementsOnASingleLine =
863         FormatStyle::SIS_WithoutElse;
864     ChromiumStyle.BreakAfterJavaFieldAnnotations = true;
865     ChromiumStyle.ContinuationIndentWidth = 8;
866     ChromiumStyle.IndentWidth = 4;
867     // See styleguide for import groups:
868     // https://chromium.googlesource.com/chromium/src/+/master/styleguide/java/java.md#Import-Order
869     ChromiumStyle.JavaImportGroups = {
870         "android",      "com",  "dalvik",
871         "junit",        "org",  "com.google.android.apps.chrome",
872         "org.chromium", "java", "javax",
873     };
874     ChromiumStyle.SortIncludes = true;
875   } else if (Language == FormatStyle::LK_JavaScript) {
876     ChromiumStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
877     ChromiumStyle.AllowShortLoopsOnASingleLine = false;
878   } else {
879     ChromiumStyle.AllowAllParametersOfDeclarationOnNextLine = false;
880     ChromiumStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
881     ChromiumStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
882     ChromiumStyle.AllowShortLoopsOnASingleLine = false;
883     ChromiumStyle.BinPackParameters = false;
884     ChromiumStyle.DerivePointerAlignment = false;
885     if (Language == FormatStyle::LK_ObjC)
886       ChromiumStyle.ColumnLimit = 80;
887   }
888   return ChromiumStyle;
889 }
890 
891 FormatStyle getMozillaStyle() {
892   FormatStyle MozillaStyle = getLLVMStyle();
893   MozillaStyle.AllowAllParametersOfDeclarationOnNextLine = false;
894   MozillaStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
895   MozillaStyle.AlwaysBreakAfterReturnType = FormatStyle::RTBS_TopLevel;
896   MozillaStyle.AlwaysBreakAfterDefinitionReturnType =
897       FormatStyle::DRTBS_TopLevel;
898   MozillaStyle.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_Yes;
899   MozillaStyle.BinPackParameters = false;
900   MozillaStyle.BinPackArguments = false;
901   MozillaStyle.BreakBeforeBraces = FormatStyle::BS_Mozilla;
902   MozillaStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma;
903   MozillaStyle.BreakInheritanceList = FormatStyle::BILS_BeforeComma;
904   MozillaStyle.ConstructorInitializerIndentWidth = 2;
905   MozillaStyle.ContinuationIndentWidth = 2;
906   MozillaStyle.Cpp11BracedListStyle = false;
907   MozillaStyle.FixNamespaceComments = false;
908   MozillaStyle.IndentCaseLabels = true;
909   MozillaStyle.ObjCSpaceAfterProperty = true;
910   MozillaStyle.ObjCSpaceBeforeProtocolList = false;
911   MozillaStyle.PenaltyReturnTypeOnItsOwnLine = 200;
912   MozillaStyle.PointerAlignment = FormatStyle::PAS_Left;
913   MozillaStyle.SpaceAfterTemplateKeyword = false;
914   return MozillaStyle;
915 }
916 
917 FormatStyle getWebKitStyle() {
918   FormatStyle Style = getLLVMStyle();
919   Style.AccessModifierOffset = -4;
920   Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign;
921   Style.AlignOperands = false;
922   Style.AlignTrailingComments = false;
923   Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All;
924   Style.BreakBeforeBraces = FormatStyle::BS_WebKit;
925   Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma;
926   Style.Cpp11BracedListStyle = false;
927   Style.ColumnLimit = 0;
928   Style.FixNamespaceComments = false;
929   Style.IndentWidth = 4;
930   Style.NamespaceIndentation = FormatStyle::NI_Inner;
931   Style.ObjCBlockIndentWidth = 4;
932   Style.ObjCSpaceAfterProperty = true;
933   Style.PointerAlignment = FormatStyle::PAS_Left;
934   Style.SpaceBeforeCpp11BracedList = true;
935   return Style;
936 }
937 
938 FormatStyle getGNUStyle() {
939   FormatStyle Style = getLLVMStyle();
940   Style.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_All;
941   Style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_AllDefinitions;
942   Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All;
943   Style.BreakBeforeBraces = FormatStyle::BS_GNU;
944   Style.BreakBeforeTernaryOperators = true;
945   Style.Cpp11BracedListStyle = false;
946   Style.ColumnLimit = 79;
947   Style.FixNamespaceComments = false;
948   Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
949   Style.Standard = FormatStyle::LS_Cpp03;
950   return Style;
951 }
952 
953 FormatStyle getNoStyle() {
954   FormatStyle NoStyle = getLLVMStyle();
955   NoStyle.DisableFormat = true;
956   NoStyle.SortIncludes = false;
957   NoStyle.SortUsingDeclarations = false;
958   return NoStyle;
959 }
960 
961 bool getPredefinedStyle(StringRef Name, FormatStyle::LanguageKind Language,
962                         FormatStyle *Style) {
963   if (Name.equals_lower("llvm")) {
964     *Style = getLLVMStyle(Language);
965   } else if (Name.equals_lower("chromium")) {
966     *Style = getChromiumStyle(Language);
967   } else if (Name.equals_lower("mozilla")) {
968     *Style = getMozillaStyle();
969   } else if (Name.equals_lower("google")) {
970     *Style = getGoogleStyle(Language);
971   } else if (Name.equals_lower("webkit")) {
972     *Style = getWebKitStyle();
973   } else if (Name.equals_lower("gnu")) {
974     *Style = getGNUStyle();
975   } else if (Name.equals_lower("none")) {
976     *Style = getNoStyle();
977   } else {
978     return false;
979   }
980 
981   Style->Language = Language;
982   return true;
983 }
984 
985 std::error_code parseConfiguration(StringRef Text, FormatStyle *Style) {
986   assert(Style);
987   FormatStyle::LanguageKind Language = Style->Language;
988   assert(Language != FormatStyle::LK_None);
989   if (Text.trim().empty())
990     return make_error_code(ParseError::Error);
991   Style->StyleSet.Clear();
992   std::vector<FormatStyle> Styles;
993   llvm::yaml::Input Input(Text);
994   // DocumentListTraits<vector<FormatStyle>> uses the context to get default
995   // values for the fields, keys for which are missing from the configuration.
996   // Mapping also uses the context to get the language to find the correct
997   // base style.
998   Input.setContext(Style);
999   Input >> Styles;
1000   if (Input.error())
1001     return Input.error();
1002 
1003   for (unsigned i = 0; i < Styles.size(); ++i) {
1004     // Ensures that only the first configuration can skip the Language option.
1005     if (Styles[i].Language == FormatStyle::LK_None && i != 0)
1006       return make_error_code(ParseError::Error);
1007     // Ensure that each language is configured at most once.
1008     for (unsigned j = 0; j < i; ++j) {
1009       if (Styles[i].Language == Styles[j].Language) {
1010         LLVM_DEBUG(llvm::dbgs()
1011                    << "Duplicate languages in the config file on positions "
1012                    << j << " and " << i << "\n");
1013         return make_error_code(ParseError::Error);
1014       }
1015     }
1016   }
1017   // Look for a suitable configuration starting from the end, so we can
1018   // find the configuration for the specific language first, and the default
1019   // configuration (which can only be at slot 0) after it.
1020   FormatStyle::FormatStyleSet StyleSet;
1021   bool LanguageFound = false;
1022   for (int i = Styles.size() - 1; i >= 0; --i) {
1023     if (Styles[i].Language != FormatStyle::LK_None)
1024       StyleSet.Add(Styles[i]);
1025     if (Styles[i].Language == Language)
1026       LanguageFound = true;
1027   }
1028   if (!LanguageFound) {
1029     if (Styles.empty() || Styles[0].Language != FormatStyle::LK_None)
1030       return make_error_code(ParseError::Unsuitable);
1031     FormatStyle DefaultStyle = Styles[0];
1032     DefaultStyle.Language = Language;
1033     StyleSet.Add(std::move(DefaultStyle));
1034   }
1035   *Style = *StyleSet.Get(Language);
1036   return make_error_code(ParseError::Success);
1037 }
1038 
1039 std::string configurationAsText(const FormatStyle &Style) {
1040   std::string Text;
1041   llvm::raw_string_ostream Stream(Text);
1042   llvm::yaml::Output Output(Stream);
1043   // We use the same mapping method for input and output, so we need a non-const
1044   // reference here.
1045   FormatStyle NonConstStyle = expandPresets(Style);
1046   Output << NonConstStyle;
1047   return Stream.str();
1048 }
1049 
1050 llvm::Optional<FormatStyle>
1051 FormatStyle::FormatStyleSet::Get(FormatStyle::LanguageKind Language) const {
1052   if (!Styles)
1053     return None;
1054   auto It = Styles->find(Language);
1055   if (It == Styles->end())
1056     return None;
1057   FormatStyle Style = It->second;
1058   Style.StyleSet = *this;
1059   return Style;
1060 }
1061 
1062 void FormatStyle::FormatStyleSet::Add(FormatStyle Style) {
1063   assert(Style.Language != LK_None &&
1064          "Cannot add a style for LK_None to a StyleSet");
1065   assert(
1066       !Style.StyleSet.Styles &&
1067       "Cannot add a style associated with an existing StyleSet to a StyleSet");
1068   if (!Styles)
1069     Styles = std::make_shared<MapType>();
1070   (*Styles)[Style.Language] = std::move(Style);
1071 }
1072 
1073 void FormatStyle::FormatStyleSet::Clear() { Styles.reset(); }
1074 
1075 llvm::Optional<FormatStyle>
1076 FormatStyle::GetLanguageStyle(FormatStyle::LanguageKind Language) const {
1077   return StyleSet.Get(Language);
1078 }
1079 
1080 namespace {
1081 
1082 class JavaScriptRequoter : public TokenAnalyzer {
1083 public:
1084   JavaScriptRequoter(const Environment &Env, const FormatStyle &Style)
1085       : TokenAnalyzer(Env, Style) {}
1086 
1087   std::pair<tooling::Replacements, unsigned>
1088   analyze(TokenAnnotator &Annotator,
1089           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
1090           FormatTokenLexer &Tokens) override {
1091     AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
1092     tooling::Replacements Result;
1093     requoteJSStringLiteral(AnnotatedLines, Result);
1094     return {Result, 0};
1095   }
1096 
1097 private:
1098   // Replaces double/single-quoted string literal as appropriate, re-escaping
1099   // the contents in the process.
1100   void requoteJSStringLiteral(SmallVectorImpl<AnnotatedLine *> &Lines,
1101                               tooling::Replacements &Result) {
1102     for (AnnotatedLine *Line : Lines) {
1103       requoteJSStringLiteral(Line->Children, Result);
1104       if (!Line->Affected)
1105         continue;
1106       for (FormatToken *FormatTok = Line->First; FormatTok;
1107            FormatTok = FormatTok->Next) {
1108         StringRef Input = FormatTok->TokenText;
1109         if (FormatTok->Finalized || !FormatTok->isStringLiteral() ||
1110             // NB: testing for not starting with a double quote to avoid
1111             // breaking `template strings`.
1112             (Style.JavaScriptQuotes == FormatStyle::JSQS_Single &&
1113              !Input.startswith("\"")) ||
1114             (Style.JavaScriptQuotes == FormatStyle::JSQS_Double &&
1115              !Input.startswith("\'")))
1116           continue;
1117 
1118         // Change start and end quote.
1119         bool IsSingle = Style.JavaScriptQuotes == FormatStyle::JSQS_Single;
1120         SourceLocation Start = FormatTok->Tok.getLocation();
1121         auto Replace = [&](SourceLocation Start, unsigned Length,
1122                            StringRef ReplacementText) {
1123           auto Err = Result.add(tooling::Replacement(
1124               Env.getSourceManager(), Start, Length, ReplacementText));
1125           // FIXME: handle error. For now, print error message and skip the
1126           // replacement for release version.
1127           if (Err) {
1128             llvm::errs() << llvm::toString(std::move(Err)) << "\n";
1129             assert(false);
1130           }
1131         };
1132         Replace(Start, 1, IsSingle ? "'" : "\"");
1133         Replace(FormatTok->Tok.getEndLoc().getLocWithOffset(-1), 1,
1134                 IsSingle ? "'" : "\"");
1135 
1136         // Escape internal quotes.
1137         bool Escaped = false;
1138         for (size_t i = 1; i < Input.size() - 1; i++) {
1139           switch (Input[i]) {
1140           case '\\':
1141             if (!Escaped && i + 1 < Input.size() &&
1142                 ((IsSingle && Input[i + 1] == '"') ||
1143                  (!IsSingle && Input[i + 1] == '\''))) {
1144               // Remove this \, it's escaping a " or ' that no longer needs
1145               // escaping
1146               Replace(Start.getLocWithOffset(i), 1, "");
1147               continue;
1148             }
1149             Escaped = !Escaped;
1150             break;
1151           case '\"':
1152           case '\'':
1153             if (!Escaped && IsSingle == (Input[i] == '\'')) {
1154               // Escape the quote.
1155               Replace(Start.getLocWithOffset(i), 0, "\\");
1156             }
1157             Escaped = false;
1158             break;
1159           default:
1160             Escaped = false;
1161             break;
1162           }
1163         }
1164       }
1165     }
1166   }
1167 };
1168 
1169 class Formatter : public TokenAnalyzer {
1170 public:
1171   Formatter(const Environment &Env, const FormatStyle &Style,
1172             FormattingAttemptStatus *Status)
1173       : TokenAnalyzer(Env, Style), Status(Status) {}
1174 
1175   std::pair<tooling::Replacements, unsigned>
1176   analyze(TokenAnnotator &Annotator,
1177           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
1178           FormatTokenLexer &Tokens) override {
1179     tooling::Replacements Result;
1180     deriveLocalStyle(AnnotatedLines);
1181     AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
1182     for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
1183       Annotator.calculateFormattingInformation(*AnnotatedLines[i]);
1184     }
1185     Annotator.setCommentLineLevels(AnnotatedLines);
1186 
1187     WhitespaceManager Whitespaces(
1188         Env.getSourceManager(), Style,
1189         inputUsesCRLF(Env.getSourceManager().getBufferData(Env.getFileID())));
1190     ContinuationIndenter Indenter(Style, Tokens.getKeywords(),
1191                                   Env.getSourceManager(), Whitespaces, Encoding,
1192                                   BinPackInconclusiveFunctions);
1193     unsigned Penalty =
1194         UnwrappedLineFormatter(&Indenter, &Whitespaces, Style,
1195                                Tokens.getKeywords(), Env.getSourceManager(),
1196                                Status)
1197             .format(AnnotatedLines, /*DryRun=*/false,
1198                     /*AdditionalIndent=*/0,
1199                     /*FixBadIndentation=*/false,
1200                     /*FirstStartColumn=*/Env.getFirstStartColumn(),
1201                     /*NextStartColumn=*/Env.getNextStartColumn(),
1202                     /*LastStartColumn=*/Env.getLastStartColumn());
1203     for (const auto &R : Whitespaces.generateReplacements())
1204       if (Result.add(R))
1205         return std::make_pair(Result, 0);
1206     return std::make_pair(Result, Penalty);
1207   }
1208 
1209 private:
1210   static bool inputUsesCRLF(StringRef Text) {
1211     return Text.count('\r') * 2 > Text.count('\n');
1212   }
1213 
1214   bool
1215   hasCpp03IncompatibleFormat(const SmallVectorImpl<AnnotatedLine *> &Lines) {
1216     for (const AnnotatedLine *Line : Lines) {
1217       if (hasCpp03IncompatibleFormat(Line->Children))
1218         return true;
1219       for (FormatToken *Tok = Line->First->Next; Tok; Tok = Tok->Next) {
1220         if (Tok->WhitespaceRange.getBegin() == Tok->WhitespaceRange.getEnd()) {
1221           if (Tok->is(tok::coloncolon) && Tok->Previous->is(TT_TemplateOpener))
1222             return true;
1223           if (Tok->is(TT_TemplateCloser) &&
1224               Tok->Previous->is(TT_TemplateCloser))
1225             return true;
1226         }
1227       }
1228     }
1229     return false;
1230   }
1231 
1232   int countVariableAlignments(const SmallVectorImpl<AnnotatedLine *> &Lines) {
1233     int AlignmentDiff = 0;
1234     for (const AnnotatedLine *Line : Lines) {
1235       AlignmentDiff += countVariableAlignments(Line->Children);
1236       for (FormatToken *Tok = Line->First; Tok && Tok->Next; Tok = Tok->Next) {
1237         if (!Tok->is(TT_PointerOrReference))
1238           continue;
1239         bool SpaceBefore =
1240             Tok->WhitespaceRange.getBegin() != Tok->WhitespaceRange.getEnd();
1241         bool SpaceAfter = Tok->Next->WhitespaceRange.getBegin() !=
1242                           Tok->Next->WhitespaceRange.getEnd();
1243         if (SpaceBefore && !SpaceAfter)
1244           ++AlignmentDiff;
1245         if (!SpaceBefore && SpaceAfter)
1246           --AlignmentDiff;
1247       }
1248     }
1249     return AlignmentDiff;
1250   }
1251 
1252   void
1253   deriveLocalStyle(const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
1254     bool HasBinPackedFunction = false;
1255     bool HasOnePerLineFunction = false;
1256     for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
1257       if (!AnnotatedLines[i]->First->Next)
1258         continue;
1259       FormatToken *Tok = AnnotatedLines[i]->First->Next;
1260       while (Tok->Next) {
1261         if (Tok->PackingKind == PPK_BinPacked)
1262           HasBinPackedFunction = true;
1263         if (Tok->PackingKind == PPK_OnePerLine)
1264           HasOnePerLineFunction = true;
1265 
1266         Tok = Tok->Next;
1267       }
1268     }
1269     if (Style.DerivePointerAlignment)
1270       Style.PointerAlignment = countVariableAlignments(AnnotatedLines) <= 0
1271                                    ? FormatStyle::PAS_Left
1272                                    : FormatStyle::PAS_Right;
1273     if (Style.Standard == FormatStyle::LS_Auto)
1274       Style.Standard = hasCpp03IncompatibleFormat(AnnotatedLines)
1275                            ? FormatStyle::LS_Cpp11
1276                            : FormatStyle::LS_Cpp03;
1277     BinPackInconclusiveFunctions =
1278         HasBinPackedFunction || !HasOnePerLineFunction;
1279   }
1280 
1281   bool BinPackInconclusiveFunctions;
1282   FormattingAttemptStatus *Status;
1283 };
1284 
1285 // This class clean up the erroneous/redundant code around the given ranges in
1286 // file.
1287 class Cleaner : public TokenAnalyzer {
1288 public:
1289   Cleaner(const Environment &Env, const FormatStyle &Style)
1290       : TokenAnalyzer(Env, Style),
1291         DeletedTokens(FormatTokenLess(Env.getSourceManager())) {}
1292 
1293   // FIXME: eliminate unused parameters.
1294   std::pair<tooling::Replacements, unsigned>
1295   analyze(TokenAnnotator &Annotator,
1296           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
1297           FormatTokenLexer &Tokens) override {
1298     // FIXME: in the current implementation the granularity of affected range
1299     // is an annotated line. However, this is not sufficient. Furthermore,
1300     // redundant code introduced by replacements does not necessarily
1301     // intercept with ranges of replacements that result in the redundancy.
1302     // To determine if some redundant code is actually introduced by
1303     // replacements(e.g. deletions), we need to come up with a more
1304     // sophisticated way of computing affected ranges.
1305     AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
1306 
1307     checkEmptyNamespace(AnnotatedLines);
1308 
1309     for (auto &Line : AnnotatedLines) {
1310       if (Line->Affected) {
1311         cleanupRight(Line->First, tok::comma, tok::comma);
1312         cleanupRight(Line->First, TT_CtorInitializerColon, tok::comma);
1313         cleanupRight(Line->First, tok::l_paren, tok::comma);
1314         cleanupLeft(Line->First, tok::comma, tok::r_paren);
1315         cleanupLeft(Line->First, TT_CtorInitializerComma, tok::l_brace);
1316         cleanupLeft(Line->First, TT_CtorInitializerColon, tok::l_brace);
1317         cleanupLeft(Line->First, TT_CtorInitializerColon, tok::equal);
1318       }
1319     }
1320 
1321     return {generateFixes(), 0};
1322   }
1323 
1324 private:
1325   bool containsOnlyComments(const AnnotatedLine &Line) {
1326     for (FormatToken *Tok = Line.First; Tok != nullptr; Tok = Tok->Next) {
1327       if (Tok->isNot(tok::comment))
1328         return false;
1329     }
1330     return true;
1331   }
1332 
1333   // Iterate through all lines and remove any empty (nested) namespaces.
1334   void checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
1335     std::set<unsigned> DeletedLines;
1336     for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
1337       auto &Line = *AnnotatedLines[i];
1338       if (Line.startsWithNamespace()) {
1339         checkEmptyNamespace(AnnotatedLines, i, i, DeletedLines);
1340       }
1341     }
1342 
1343     for (auto Line : DeletedLines) {
1344       FormatToken *Tok = AnnotatedLines[Line]->First;
1345       while (Tok) {
1346         deleteToken(Tok);
1347         Tok = Tok->Next;
1348       }
1349     }
1350   }
1351 
1352   // The function checks if the namespace, which starts from \p CurrentLine, and
1353   // its nested namespaces are empty and delete them if they are empty. It also
1354   // sets \p NewLine to the last line checked.
1355   // Returns true if the current namespace is empty.
1356   bool checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
1357                            unsigned CurrentLine, unsigned &NewLine,
1358                            std::set<unsigned> &DeletedLines) {
1359     unsigned InitLine = CurrentLine, End = AnnotatedLines.size();
1360     if (Style.BraceWrapping.AfterNamespace) {
1361       // If the left brace is in a new line, we should consume it first so that
1362       // it does not make the namespace non-empty.
1363       // FIXME: error handling if there is no left brace.
1364       if (!AnnotatedLines[++CurrentLine]->startsWith(tok::l_brace)) {
1365         NewLine = CurrentLine;
1366         return false;
1367       }
1368     } else if (!AnnotatedLines[CurrentLine]->endsWith(tok::l_brace)) {
1369       return false;
1370     }
1371     while (++CurrentLine < End) {
1372       if (AnnotatedLines[CurrentLine]->startsWith(tok::r_brace))
1373         break;
1374 
1375       if (AnnotatedLines[CurrentLine]->startsWithNamespace()) {
1376         if (!checkEmptyNamespace(AnnotatedLines, CurrentLine, NewLine,
1377                                  DeletedLines))
1378           return false;
1379         CurrentLine = NewLine;
1380         continue;
1381       }
1382 
1383       if (containsOnlyComments(*AnnotatedLines[CurrentLine]))
1384         continue;
1385 
1386       // If there is anything other than comments or nested namespaces in the
1387       // current namespace, the namespace cannot be empty.
1388       NewLine = CurrentLine;
1389       return false;
1390     }
1391 
1392     NewLine = CurrentLine;
1393     if (CurrentLine >= End)
1394       return false;
1395 
1396     // Check if the empty namespace is actually affected by changed ranges.
1397     if (!AffectedRangeMgr.affectsCharSourceRange(CharSourceRange::getCharRange(
1398             AnnotatedLines[InitLine]->First->Tok.getLocation(),
1399             AnnotatedLines[CurrentLine]->Last->Tok.getEndLoc())))
1400       return false;
1401 
1402     for (unsigned i = InitLine; i <= CurrentLine; ++i) {
1403       DeletedLines.insert(i);
1404     }
1405 
1406     return true;
1407   }
1408 
1409   // Checks pairs {start, start->next},..., {end->previous, end} and deletes one
1410   // of the token in the pair if the left token has \p LK token kind and the
1411   // right token has \p RK token kind. If \p DeleteLeft is true, the left token
1412   // is deleted on match; otherwise, the right token is deleted.
1413   template <typename LeftKind, typename RightKind>
1414   void cleanupPair(FormatToken *Start, LeftKind LK, RightKind RK,
1415                    bool DeleteLeft) {
1416     auto NextNotDeleted = [this](const FormatToken &Tok) -> FormatToken * {
1417       for (auto *Res = Tok.Next; Res; Res = Res->Next)
1418         if (!Res->is(tok::comment) &&
1419             DeletedTokens.find(Res) == DeletedTokens.end())
1420           return Res;
1421       return nullptr;
1422     };
1423     for (auto *Left = Start; Left;) {
1424       auto *Right = NextNotDeleted(*Left);
1425       if (!Right)
1426         break;
1427       if (Left->is(LK) && Right->is(RK)) {
1428         deleteToken(DeleteLeft ? Left : Right);
1429         for (auto *Tok = Left->Next; Tok && Tok != Right; Tok = Tok->Next)
1430           deleteToken(Tok);
1431         // If the right token is deleted, we should keep the left token
1432         // unchanged and pair it with the new right token.
1433         if (!DeleteLeft)
1434           continue;
1435       }
1436       Left = Right;
1437     }
1438   }
1439 
1440   template <typename LeftKind, typename RightKind>
1441   void cleanupLeft(FormatToken *Start, LeftKind LK, RightKind RK) {
1442     cleanupPair(Start, LK, RK, /*DeleteLeft=*/true);
1443   }
1444 
1445   template <typename LeftKind, typename RightKind>
1446   void cleanupRight(FormatToken *Start, LeftKind LK, RightKind RK) {
1447     cleanupPair(Start, LK, RK, /*DeleteLeft=*/false);
1448   }
1449 
1450   // Delete the given token.
1451   inline void deleteToken(FormatToken *Tok) {
1452     if (Tok)
1453       DeletedTokens.insert(Tok);
1454   }
1455 
1456   tooling::Replacements generateFixes() {
1457     tooling::Replacements Fixes;
1458     std::vector<FormatToken *> Tokens;
1459     std::copy(DeletedTokens.begin(), DeletedTokens.end(),
1460               std::back_inserter(Tokens));
1461 
1462     // Merge multiple continuous token deletions into one big deletion so that
1463     // the number of replacements can be reduced. This makes computing affected
1464     // ranges more efficient when we run reformat on the changed code.
1465     unsigned Idx = 0;
1466     while (Idx < Tokens.size()) {
1467       unsigned St = Idx, End = Idx;
1468       while ((End + 1) < Tokens.size() &&
1469              Tokens[End]->Next == Tokens[End + 1]) {
1470         End++;
1471       }
1472       auto SR = CharSourceRange::getCharRange(Tokens[St]->Tok.getLocation(),
1473                                               Tokens[End]->Tok.getEndLoc());
1474       auto Err =
1475           Fixes.add(tooling::Replacement(Env.getSourceManager(), SR, ""));
1476       // FIXME: better error handling. for now just print error message and skip
1477       // for the release version.
1478       if (Err) {
1479         llvm::errs() << llvm::toString(std::move(Err)) << "\n";
1480         assert(false && "Fixes must not conflict!");
1481       }
1482       Idx = End + 1;
1483     }
1484 
1485     return Fixes;
1486   }
1487 
1488   // Class for less-than inequality comparason for the set `RedundantTokens`.
1489   // We store tokens in the order they appear in the translation unit so that
1490   // we do not need to sort them in `generateFixes()`.
1491   struct FormatTokenLess {
1492     FormatTokenLess(const SourceManager &SM) : SM(SM) {}
1493 
1494     bool operator()(const FormatToken *LHS, const FormatToken *RHS) const {
1495       return SM.isBeforeInTranslationUnit(LHS->Tok.getLocation(),
1496                                           RHS->Tok.getLocation());
1497     }
1498     const SourceManager &SM;
1499   };
1500 
1501   // Tokens to be deleted.
1502   std::set<FormatToken *, FormatTokenLess> DeletedTokens;
1503 };
1504 
1505 class ObjCHeaderStyleGuesser : public TokenAnalyzer {
1506 public:
1507   ObjCHeaderStyleGuesser(const Environment &Env, const FormatStyle &Style)
1508       : TokenAnalyzer(Env, Style), IsObjC(false) {}
1509 
1510   std::pair<tooling::Replacements, unsigned>
1511   analyze(TokenAnnotator &Annotator,
1512           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
1513           FormatTokenLexer &Tokens) override {
1514     assert(Style.Language == FormatStyle::LK_Cpp);
1515     IsObjC = guessIsObjC(Env.getSourceManager(), AnnotatedLines,
1516                          Tokens.getKeywords());
1517     tooling::Replacements Result;
1518     return {Result, 0};
1519   }
1520 
1521   bool isObjC() { return IsObjC; }
1522 
1523 private:
1524   static bool
1525   guessIsObjC(const SourceManager &SourceManager,
1526               const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
1527               const AdditionalKeywords &Keywords) {
1528     // Keep this array sorted, since we are binary searching over it.
1529     static constexpr llvm::StringLiteral FoundationIdentifiers[] = {
1530         "CGFloat",
1531         "CGPoint",
1532         "CGPointMake",
1533         "CGPointZero",
1534         "CGRect",
1535         "CGRectEdge",
1536         "CGRectInfinite",
1537         "CGRectMake",
1538         "CGRectNull",
1539         "CGRectZero",
1540         "CGSize",
1541         "CGSizeMake",
1542         "CGVector",
1543         "CGVectorMake",
1544         "NSAffineTransform",
1545         "NSArray",
1546         "NSAttributedString",
1547         "NSBlockOperation",
1548         "NSBundle",
1549         "NSCache",
1550         "NSCalendar",
1551         "NSCharacterSet",
1552         "NSCountedSet",
1553         "NSData",
1554         "NSDataDetector",
1555         "NSDecimal",
1556         "NSDecimalNumber",
1557         "NSDictionary",
1558         "NSEdgeInsets",
1559         "NSHashTable",
1560         "NSIndexPath",
1561         "NSIndexSet",
1562         "NSInteger",
1563         "NSInvocationOperation",
1564         "NSLocale",
1565         "NSMapTable",
1566         "NSMutableArray",
1567         "NSMutableAttributedString",
1568         "NSMutableCharacterSet",
1569         "NSMutableData",
1570         "NSMutableDictionary",
1571         "NSMutableIndexSet",
1572         "NSMutableOrderedSet",
1573         "NSMutableSet",
1574         "NSMutableString",
1575         "NSNumber",
1576         "NSNumberFormatter",
1577         "NSObject",
1578         "NSOperation",
1579         "NSOperationQueue",
1580         "NSOperationQueuePriority",
1581         "NSOrderedSet",
1582         "NSPoint",
1583         "NSPointerArray",
1584         "NSQualityOfService",
1585         "NSRange",
1586         "NSRect",
1587         "NSRegularExpression",
1588         "NSSet",
1589         "NSSize",
1590         "NSString",
1591         "NSTimeZone",
1592         "NSUInteger",
1593         "NSURL",
1594         "NSURLComponents",
1595         "NSURLQueryItem",
1596         "NSUUID",
1597         "NSValue",
1598         "UIImage",
1599         "UIView",
1600     };
1601 
1602     for (auto Line : AnnotatedLines) {
1603       for (const FormatToken *FormatTok = Line->First; FormatTok;
1604            FormatTok = FormatTok->Next) {
1605         if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) &&
1606              (FormatTok->Tok.getObjCKeywordID() != tok::objc_not_keyword ||
1607               FormatTok->isOneOf(tok::numeric_constant, tok::l_square,
1608                                  tok::l_brace))) ||
1609             (FormatTok->Tok.isAnyIdentifier() &&
1610              std::binary_search(std::begin(FoundationIdentifiers),
1611                                 std::end(FoundationIdentifiers),
1612                                 FormatTok->TokenText)) ||
1613             FormatTok->is(TT_ObjCStringLiteral) ||
1614             FormatTok->isOneOf(Keywords.kw_NS_ENUM, Keywords.kw_NS_OPTIONS,
1615                                TT_ObjCBlockLBrace, TT_ObjCBlockLParen,
1616                                TT_ObjCDecl, TT_ObjCForIn, TT_ObjCMethodExpr,
1617                                TT_ObjCMethodSpecifier, TT_ObjCProperty)) {
1618           LLVM_DEBUG(llvm::dbgs()
1619                      << "Detected ObjC at location "
1620                      << FormatTok->Tok.getLocation().printToString(
1621                             SourceManager)
1622                      << " token: " << FormatTok->TokenText << " token type: "
1623                      << getTokenTypeName(FormatTok->Type) << "\n");
1624           return true;
1625         }
1626         if (guessIsObjC(SourceManager, Line->Children, Keywords))
1627           return true;
1628       }
1629     }
1630     return false;
1631   }
1632 
1633   bool IsObjC;
1634 };
1635 
1636 struct IncludeDirective {
1637   StringRef Filename;
1638   StringRef Text;
1639   unsigned Offset;
1640   int Category;
1641 };
1642 
1643 struct JavaImportDirective {
1644   StringRef Identifier;
1645   StringRef Text;
1646   unsigned Offset;
1647   std::vector<StringRef> AssociatedCommentLines;
1648   bool IsStatic;
1649 };
1650 
1651 } // end anonymous namespace
1652 
1653 // Determines whether 'Ranges' intersects with ('Start', 'End').
1654 static bool affectsRange(ArrayRef<tooling::Range> Ranges, unsigned Start,
1655                          unsigned End) {
1656   for (auto Range : Ranges) {
1657     if (Range.getOffset() < End &&
1658         Range.getOffset() + Range.getLength() > Start)
1659       return true;
1660   }
1661   return false;
1662 }
1663 
1664 // Returns a pair (Index, OffsetToEOL) describing the position of the cursor
1665 // before sorting/deduplicating. Index is the index of the include under the
1666 // cursor in the original set of includes. If this include has duplicates, it is
1667 // the index of the first of the duplicates as the others are going to be
1668 // removed. OffsetToEOL describes the cursor's position relative to the end of
1669 // its current line.
1670 // If `Cursor` is not on any #include, `Index` will be UINT_MAX.
1671 static std::pair<unsigned, unsigned>
1672 FindCursorIndex(const SmallVectorImpl<IncludeDirective> &Includes,
1673                 const SmallVectorImpl<unsigned> &Indices, unsigned Cursor) {
1674   unsigned CursorIndex = UINT_MAX;
1675   unsigned OffsetToEOL = 0;
1676   for (int i = 0, e = Includes.size(); i != e; ++i) {
1677     unsigned Start = Includes[Indices[i]].Offset;
1678     unsigned End = Start + Includes[Indices[i]].Text.size();
1679     if (!(Cursor >= Start && Cursor < End))
1680       continue;
1681     CursorIndex = Indices[i];
1682     OffsetToEOL = End - Cursor;
1683     // Put the cursor on the only remaining #include among the duplicate
1684     // #includes.
1685     while (--i >= 0 && Includes[CursorIndex].Text == Includes[Indices[i]].Text)
1686       CursorIndex = i;
1687     break;
1688   }
1689   return std::make_pair(CursorIndex, OffsetToEOL);
1690 }
1691 
1692 // Sorts and deduplicate a block of includes given by 'Includes' alphabetically
1693 // adding the necessary replacement to 'Replaces'. 'Includes' must be in strict
1694 // source order.
1695 // #include directives with the same text will be deduplicated, and only the
1696 // first #include in the duplicate #includes remains. If the `Cursor` is
1697 // provided and put on a deleted #include, it will be moved to the remaining
1698 // #include in the duplicate #includes.
1699 static void sortCppIncludes(const FormatStyle &Style,
1700                             const SmallVectorImpl<IncludeDirective> &Includes,
1701                             ArrayRef<tooling::Range> Ranges, StringRef FileName,
1702                             tooling::Replacements &Replaces, unsigned *Cursor) {
1703   unsigned IncludesBeginOffset = Includes.front().Offset;
1704   unsigned IncludesEndOffset =
1705       Includes.back().Offset + Includes.back().Text.size();
1706   unsigned IncludesBlockSize = IncludesEndOffset - IncludesBeginOffset;
1707   if (!affectsRange(Ranges, IncludesBeginOffset, IncludesEndOffset))
1708     return;
1709   SmallVector<unsigned, 16> Indices;
1710   for (unsigned i = 0, e = Includes.size(); i != e; ++i)
1711     Indices.push_back(i);
1712   std::stable_sort(
1713       Indices.begin(), Indices.end(), [&](unsigned LHSI, unsigned RHSI) {
1714         return std::tie(Includes[LHSI].Category, Includes[LHSI].Filename) <
1715                std::tie(Includes[RHSI].Category, Includes[RHSI].Filename);
1716       });
1717   // The index of the include on which the cursor will be put after
1718   // sorting/deduplicating.
1719   unsigned CursorIndex;
1720   // The offset from cursor to the end of line.
1721   unsigned CursorToEOLOffset;
1722   if (Cursor)
1723     std::tie(CursorIndex, CursorToEOLOffset) =
1724         FindCursorIndex(Includes, Indices, *Cursor);
1725 
1726   // Deduplicate #includes.
1727   Indices.erase(std::unique(Indices.begin(), Indices.end(),
1728                             [&](unsigned LHSI, unsigned RHSI) {
1729                               return Includes[LHSI].Text == Includes[RHSI].Text;
1730                             }),
1731                 Indices.end());
1732 
1733   int CurrentCategory = Includes.front().Category;
1734 
1735   // If the #includes are out of order, we generate a single replacement fixing
1736   // the entire block. Otherwise, no replacement is generated.
1737   if (Indices.size() == Includes.size() &&
1738       std::is_sorted(Indices.begin(), Indices.end()) &&
1739       Style.IncludeStyle.IncludeBlocks == tooling::IncludeStyle::IBS_Preserve)
1740     return;
1741 
1742   std::string result;
1743   for (unsigned Index : Indices) {
1744     if (!result.empty()) {
1745       result += "\n";
1746       if (Style.IncludeStyle.IncludeBlocks ==
1747               tooling::IncludeStyle::IBS_Regroup &&
1748           CurrentCategory != Includes[Index].Category)
1749         result += "\n";
1750     }
1751     result += Includes[Index].Text;
1752     if (Cursor && CursorIndex == Index)
1753       *Cursor = IncludesBeginOffset + result.size() - CursorToEOLOffset;
1754     CurrentCategory = Includes[Index].Category;
1755   }
1756 
1757   auto Err = Replaces.add(tooling::Replacement(
1758       FileName, Includes.front().Offset, IncludesBlockSize, result));
1759   // FIXME: better error handling. For now, just skip the replacement for the
1760   // release version.
1761   if (Err) {
1762     llvm::errs() << llvm::toString(std::move(Err)) << "\n";
1763     assert(false);
1764   }
1765 }
1766 
1767 namespace {
1768 
1769 const char CppIncludeRegexPattern[] =
1770     R"(^[\t\ ]*#[\t\ ]*(import|include)[^"<]*(["<][^">]*[">]))";
1771 
1772 } // anonymous namespace
1773 
1774 tooling::Replacements sortCppIncludes(const FormatStyle &Style, StringRef Code,
1775                                       ArrayRef<tooling::Range> Ranges,
1776                                       StringRef FileName,
1777                                       tooling::Replacements &Replaces,
1778                                       unsigned *Cursor) {
1779   unsigned Prev = 0;
1780   unsigned SearchFrom = 0;
1781   llvm::Regex IncludeRegex(CppIncludeRegexPattern);
1782   SmallVector<StringRef, 4> Matches;
1783   SmallVector<IncludeDirective, 16> IncludesInBlock;
1784 
1785   // In compiled files, consider the first #include to be the main #include of
1786   // the file if it is not a system #include. This ensures that the header
1787   // doesn't have hidden dependencies
1788   // (http://llvm.org/docs/CodingStandards.html#include-style).
1789   //
1790   // FIXME: Do some sanity checking, e.g. edit distance of the base name, to fix
1791   // cases where the first #include is unlikely to be the main header.
1792   tooling::IncludeCategoryManager Categories(Style.IncludeStyle, FileName);
1793   bool FirstIncludeBlock = true;
1794   bool MainIncludeFound = false;
1795   bool FormattingOff = false;
1796 
1797   for (;;) {
1798     auto Pos = Code.find('\n', SearchFrom);
1799     StringRef Line =
1800         Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
1801 
1802     StringRef Trimmed = Line.trim();
1803     if (Trimmed == "// clang-format off" || Trimmed == "/* clang-format off */")
1804       FormattingOff = true;
1805     else if (Trimmed == "// clang-format on" ||
1806              Trimmed == "/* clang-format on */")
1807       FormattingOff = false;
1808 
1809     const bool EmptyLineSkipped =
1810         Trimmed.empty() &&
1811         (Style.IncludeStyle.IncludeBlocks == tooling::IncludeStyle::IBS_Merge ||
1812          Style.IncludeStyle.IncludeBlocks ==
1813              tooling::IncludeStyle::IBS_Regroup);
1814 
1815     if (!FormattingOff && !Line.endswith("\\")) {
1816       if (IncludeRegex.match(Line, &Matches)) {
1817         StringRef IncludeName = Matches[2];
1818         int Category = Categories.getIncludePriority(
1819             IncludeName,
1820             /*CheckMainHeader=*/!MainIncludeFound && FirstIncludeBlock);
1821         if (Category == 0)
1822           MainIncludeFound = true;
1823         IncludesInBlock.push_back({IncludeName, Line, Prev, Category});
1824       } else if (!IncludesInBlock.empty() && !EmptyLineSkipped) {
1825         sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Replaces,
1826                         Cursor);
1827         IncludesInBlock.clear();
1828         FirstIncludeBlock = false;
1829       }
1830       Prev = Pos + 1;
1831     }
1832     if (Pos == StringRef::npos || Pos + 1 == Code.size())
1833       break;
1834     SearchFrom = Pos + 1;
1835   }
1836   if (!IncludesInBlock.empty())
1837     sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Replaces, Cursor);
1838   return Replaces;
1839 }
1840 
1841 // Returns group number to use as a first order sort on imports. Gives UINT_MAX
1842 // if the import does not match any given groups.
1843 static unsigned findJavaImportGroup(const FormatStyle &Style,
1844                                     StringRef ImportIdentifier) {
1845   unsigned LongestMatchIndex = UINT_MAX;
1846   unsigned LongestMatchLength = 0;
1847   for (unsigned I = 0; I < Style.JavaImportGroups.size(); I++) {
1848     std::string GroupPrefix = Style.JavaImportGroups[I];
1849     if (ImportIdentifier.startswith(GroupPrefix) &&
1850         GroupPrefix.length() > LongestMatchLength) {
1851       LongestMatchIndex = I;
1852       LongestMatchLength = GroupPrefix.length();
1853     }
1854   }
1855   return LongestMatchIndex;
1856 }
1857 
1858 // Sorts and deduplicates a block of includes given by 'Imports' based on
1859 // JavaImportGroups, then adding the necessary replacement to 'Replaces'.
1860 // Import declarations with the same text will be deduplicated. Between each
1861 // import group, a newline is inserted, and within each import group, a
1862 // lexicographic sort based on ASCII value is performed.
1863 static void sortJavaImports(const FormatStyle &Style,
1864                             const SmallVectorImpl<JavaImportDirective> &Imports,
1865                             ArrayRef<tooling::Range> Ranges, StringRef FileName,
1866                             StringRef Code, tooling::Replacements &Replaces) {
1867   unsigned ImportsBeginOffset = Imports.front().Offset;
1868   unsigned ImportsEndOffset =
1869       Imports.back().Offset + Imports.back().Text.size();
1870   unsigned ImportsBlockSize = ImportsEndOffset - ImportsBeginOffset;
1871   if (!affectsRange(Ranges, ImportsBeginOffset, ImportsEndOffset))
1872     return;
1873   SmallVector<unsigned, 16> Indices;
1874   SmallVector<unsigned, 16> JavaImportGroups;
1875   for (unsigned i = 0, e = Imports.size(); i != e; ++i) {
1876     Indices.push_back(i);
1877     JavaImportGroups.push_back(
1878         findJavaImportGroup(Style, Imports[i].Identifier));
1879   }
1880   llvm::sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
1881     // Negating IsStatic to push static imports above non-static imports.
1882     return std::make_tuple(!Imports[LHSI].IsStatic, JavaImportGroups[LHSI],
1883                            Imports[LHSI].Identifier) <
1884            std::make_tuple(!Imports[RHSI].IsStatic, JavaImportGroups[RHSI],
1885                            Imports[RHSI].Identifier);
1886   });
1887 
1888   // Deduplicate imports.
1889   Indices.erase(std::unique(Indices.begin(), Indices.end(),
1890                             [&](unsigned LHSI, unsigned RHSI) {
1891                               return Imports[LHSI].Text == Imports[RHSI].Text;
1892                             }),
1893                 Indices.end());
1894 
1895   bool CurrentIsStatic = Imports[Indices.front()].IsStatic;
1896   unsigned CurrentImportGroup = JavaImportGroups[Indices.front()];
1897 
1898   std::string result;
1899   for (unsigned Index : Indices) {
1900     if (!result.empty()) {
1901       result += "\n";
1902       if (CurrentIsStatic != Imports[Index].IsStatic ||
1903           CurrentImportGroup != JavaImportGroups[Index])
1904         result += "\n";
1905     }
1906     for (StringRef CommentLine : Imports[Index].AssociatedCommentLines) {
1907       result += CommentLine;
1908       result += "\n";
1909     }
1910     result += Imports[Index].Text;
1911     CurrentIsStatic = Imports[Index].IsStatic;
1912     CurrentImportGroup = JavaImportGroups[Index];
1913   }
1914 
1915   // If the imports are out of order, we generate a single replacement fixing
1916   // the entire block. Otherwise, no replacement is generated.
1917   if (result == Code.substr(Imports.front().Offset, ImportsBlockSize))
1918     return;
1919 
1920   auto Err = Replaces.add(tooling::Replacement(FileName, Imports.front().Offset,
1921                                                ImportsBlockSize, result));
1922   // FIXME: better error handling. For now, just skip the replacement for the
1923   // release version.
1924   if (Err) {
1925     llvm::errs() << llvm::toString(std::move(Err)) << "\n";
1926     assert(false);
1927   }
1928 }
1929 
1930 namespace {
1931 
1932 const char JavaImportRegexPattern[] =
1933     "^[\t ]*import[\t ]*(static[\t ]*)?([^\t ]*)[\t ]*;";
1934 
1935 } // anonymous namespace
1936 
1937 tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code,
1938                                       ArrayRef<tooling::Range> Ranges,
1939                                       StringRef FileName,
1940                                       tooling::Replacements &Replaces) {
1941   unsigned Prev = 0;
1942   unsigned SearchFrom = 0;
1943   llvm::Regex ImportRegex(JavaImportRegexPattern);
1944   SmallVector<StringRef, 4> Matches;
1945   SmallVector<JavaImportDirective, 16> ImportsInBlock;
1946   std::vector<StringRef> AssociatedCommentLines;
1947 
1948   bool FormattingOff = false;
1949 
1950   for (;;) {
1951     auto Pos = Code.find('\n', SearchFrom);
1952     StringRef Line =
1953         Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
1954 
1955     StringRef Trimmed = Line.trim();
1956     if (Trimmed == "// clang-format off")
1957       FormattingOff = true;
1958     else if (Trimmed == "// clang-format on")
1959       FormattingOff = false;
1960 
1961     if (ImportRegex.match(Line, &Matches)) {
1962       if (FormattingOff) {
1963         // If at least one import line has formatting turned off, turn off
1964         // formatting entirely.
1965         return Replaces;
1966       }
1967       StringRef Static = Matches[1];
1968       StringRef Identifier = Matches[2];
1969       bool IsStatic = false;
1970       if (Static.contains("static")) {
1971         IsStatic = true;
1972       }
1973       ImportsInBlock.push_back(
1974           {Identifier, Line, Prev, AssociatedCommentLines, IsStatic});
1975       AssociatedCommentLines.clear();
1976     } else if (Trimmed.size() > 0 && !ImportsInBlock.empty()) {
1977       // Associating comments within the imports with the nearest import below
1978       AssociatedCommentLines.push_back(Line);
1979     }
1980     Prev = Pos + 1;
1981     if (Pos == StringRef::npos || Pos + 1 == Code.size())
1982       break;
1983     SearchFrom = Pos + 1;
1984   }
1985   if (!ImportsInBlock.empty())
1986     sortJavaImports(Style, ImportsInBlock, Ranges, FileName, Code, Replaces);
1987   return Replaces;
1988 }
1989 
1990 bool isMpegTS(StringRef Code) {
1991   // MPEG transport streams use the ".ts" file extension. clang-format should
1992   // not attempt to format those. MPEG TS' frame format starts with 0x47 every
1993   // 189 bytes - detect that and return.
1994   return Code.size() > 188 && Code[0] == 0x47 && Code[188] == 0x47;
1995 }
1996 
1997 bool isLikelyXml(StringRef Code) { return Code.ltrim().startswith("<"); }
1998 
1999 tooling::Replacements sortIncludes(const FormatStyle &Style, StringRef Code,
2000                                    ArrayRef<tooling::Range> Ranges,
2001                                    StringRef FileName, unsigned *Cursor) {
2002   tooling::Replacements Replaces;
2003   if (!Style.SortIncludes)
2004     return Replaces;
2005   if (isLikelyXml(Code))
2006     return Replaces;
2007   if (Style.Language == FormatStyle::LanguageKind::LK_JavaScript &&
2008       isMpegTS(Code))
2009     return Replaces;
2010   if (Style.Language == FormatStyle::LanguageKind::LK_JavaScript)
2011     return sortJavaScriptImports(Style, Code, Ranges, FileName);
2012   if (Style.Language == FormatStyle::LanguageKind::LK_Java)
2013     return sortJavaImports(Style, Code, Ranges, FileName, Replaces);
2014   sortCppIncludes(Style, Code, Ranges, FileName, Replaces, Cursor);
2015   return Replaces;
2016 }
2017 
2018 template <typename T>
2019 static llvm::Expected<tooling::Replacements>
2020 processReplacements(T ProcessFunc, StringRef Code,
2021                     const tooling::Replacements &Replaces,
2022                     const FormatStyle &Style) {
2023   if (Replaces.empty())
2024     return tooling::Replacements();
2025 
2026   auto NewCode = applyAllReplacements(Code, Replaces);
2027   if (!NewCode)
2028     return NewCode.takeError();
2029   std::vector<tooling::Range> ChangedRanges = Replaces.getAffectedRanges();
2030   StringRef FileName = Replaces.begin()->getFilePath();
2031 
2032   tooling::Replacements FormatReplaces =
2033       ProcessFunc(Style, *NewCode, ChangedRanges, FileName);
2034 
2035   return Replaces.merge(FormatReplaces);
2036 }
2037 
2038 llvm::Expected<tooling::Replacements>
2039 formatReplacements(StringRef Code, const tooling::Replacements &Replaces,
2040                    const FormatStyle &Style) {
2041   // We need to use lambda function here since there are two versions of
2042   // `sortIncludes`.
2043   auto SortIncludes = [](const FormatStyle &Style, StringRef Code,
2044                          std::vector<tooling::Range> Ranges,
2045                          StringRef FileName) -> tooling::Replacements {
2046     return sortIncludes(Style, Code, Ranges, FileName);
2047   };
2048   auto SortedReplaces =
2049       processReplacements(SortIncludes, Code, Replaces, Style);
2050   if (!SortedReplaces)
2051     return SortedReplaces.takeError();
2052 
2053   // We need to use lambda function here since there are two versions of
2054   // `reformat`.
2055   auto Reformat = [](const FormatStyle &Style, StringRef Code,
2056                      std::vector<tooling::Range> Ranges,
2057                      StringRef FileName) -> tooling::Replacements {
2058     return reformat(Style, Code, Ranges, FileName);
2059   };
2060   return processReplacements(Reformat, Code, *SortedReplaces, Style);
2061 }
2062 
2063 namespace {
2064 
2065 inline bool isHeaderInsertion(const tooling::Replacement &Replace) {
2066   return Replace.getOffset() == UINT_MAX && Replace.getLength() == 0 &&
2067          llvm::Regex(CppIncludeRegexPattern)
2068              .match(Replace.getReplacementText());
2069 }
2070 
2071 inline bool isHeaderDeletion(const tooling::Replacement &Replace) {
2072   return Replace.getOffset() == UINT_MAX && Replace.getLength() == 1;
2073 }
2074 
2075 // FIXME: insert empty lines between newly created blocks.
2076 tooling::Replacements
2077 fixCppIncludeInsertions(StringRef Code, const tooling::Replacements &Replaces,
2078                         const FormatStyle &Style) {
2079   if (!Style.isCpp())
2080     return Replaces;
2081 
2082   tooling::Replacements HeaderInsertions;
2083   std::set<llvm::StringRef> HeadersToDelete;
2084   tooling::Replacements Result;
2085   for (const auto &R : Replaces) {
2086     if (isHeaderInsertion(R)) {
2087       // Replacements from \p Replaces must be conflict-free already, so we can
2088       // simply consume the error.
2089       llvm::consumeError(HeaderInsertions.add(R));
2090     } else if (isHeaderDeletion(R)) {
2091       HeadersToDelete.insert(R.getReplacementText());
2092     } else if (R.getOffset() == UINT_MAX) {
2093       llvm::errs() << "Insertions other than header #include insertion are "
2094                       "not supported! "
2095                    << R.getReplacementText() << "\n";
2096     } else {
2097       llvm::consumeError(Result.add(R));
2098     }
2099   }
2100   if (HeaderInsertions.empty() && HeadersToDelete.empty())
2101     return Replaces;
2102 
2103   StringRef FileName = Replaces.begin()->getFilePath();
2104   tooling::HeaderIncludes Includes(FileName, Code, Style.IncludeStyle);
2105 
2106   for (const auto &Header : HeadersToDelete) {
2107     tooling::Replacements Replaces =
2108         Includes.remove(Header.trim("\"<>"), Header.startswith("<"));
2109     for (const auto &R : Replaces) {
2110       auto Err = Result.add(R);
2111       if (Err) {
2112         // Ignore the deletion on conflict.
2113         llvm::errs() << "Failed to add header deletion replacement for "
2114                      << Header << ": " << llvm::toString(std::move(Err))
2115                      << "\n";
2116       }
2117     }
2118   }
2119 
2120   llvm::Regex IncludeRegex = llvm::Regex(CppIncludeRegexPattern);
2121   llvm::SmallVector<StringRef, 4> Matches;
2122   for (const auto &R : HeaderInsertions) {
2123     auto IncludeDirective = R.getReplacementText();
2124     bool Matched = IncludeRegex.match(IncludeDirective, &Matches);
2125     assert(Matched && "Header insertion replacement must have replacement text "
2126                       "'#include ...'");
2127     (void)Matched;
2128     auto IncludeName = Matches[2];
2129     auto Replace =
2130         Includes.insert(IncludeName.trim("\"<>"), IncludeName.startswith("<"));
2131     if (Replace) {
2132       auto Err = Result.add(*Replace);
2133       if (Err) {
2134         llvm::consumeError(std::move(Err));
2135         unsigned NewOffset =
2136             Result.getShiftedCodePosition(Replace->getOffset());
2137         auto Shifted = tooling::Replacement(FileName, NewOffset, 0,
2138                                             Replace->getReplacementText());
2139         Result = Result.merge(tooling::Replacements(Shifted));
2140       }
2141     }
2142   }
2143   return Result;
2144 }
2145 
2146 } // anonymous namespace
2147 
2148 llvm::Expected<tooling::Replacements>
2149 cleanupAroundReplacements(StringRef Code, const tooling::Replacements &Replaces,
2150                           const FormatStyle &Style) {
2151   // We need to use lambda function here since there are two versions of
2152   // `cleanup`.
2153   auto Cleanup = [](const FormatStyle &Style, StringRef Code,
2154                     std::vector<tooling::Range> Ranges,
2155                     StringRef FileName) -> tooling::Replacements {
2156     return cleanup(Style, Code, Ranges, FileName);
2157   };
2158   // Make header insertion replacements insert new headers into correct blocks.
2159   tooling::Replacements NewReplaces =
2160       fixCppIncludeInsertions(Code, Replaces, Style);
2161   return processReplacements(Cleanup, Code, NewReplaces, Style);
2162 }
2163 
2164 namespace internal {
2165 std::pair<tooling::Replacements, unsigned>
2166 reformat(const FormatStyle &Style, StringRef Code,
2167          ArrayRef<tooling::Range> Ranges, unsigned FirstStartColumn,
2168          unsigned NextStartColumn, unsigned LastStartColumn, StringRef FileName,
2169          FormattingAttemptStatus *Status) {
2170   FormatStyle Expanded = expandPresets(Style);
2171   if (Expanded.DisableFormat)
2172     return {tooling::Replacements(), 0};
2173   if (isLikelyXml(Code))
2174     return {tooling::Replacements(), 0};
2175   if (Expanded.Language == FormatStyle::LK_JavaScript && isMpegTS(Code))
2176     return {tooling::Replacements(), 0};
2177 
2178   typedef std::function<std::pair<tooling::Replacements, unsigned>(
2179       const Environment &)>
2180       AnalyzerPass;
2181   SmallVector<AnalyzerPass, 4> Passes;
2182 
2183   if (Style.Language == FormatStyle::LK_Cpp) {
2184     if (Style.FixNamespaceComments)
2185       Passes.emplace_back([&](const Environment &Env) {
2186         return NamespaceEndCommentsFixer(Env, Expanded).process();
2187       });
2188 
2189     if (Style.SortUsingDeclarations)
2190       Passes.emplace_back([&](const Environment &Env) {
2191         return UsingDeclarationsSorter(Env, Expanded).process();
2192       });
2193   }
2194 
2195   if (Style.Language == FormatStyle::LK_JavaScript &&
2196       Style.JavaScriptQuotes != FormatStyle::JSQS_Leave)
2197     Passes.emplace_back([&](const Environment &Env) {
2198       return JavaScriptRequoter(Env, Expanded).process();
2199     });
2200 
2201   Passes.emplace_back([&](const Environment &Env) {
2202     return Formatter(Env, Expanded, Status).process();
2203   });
2204 
2205   auto Env =
2206       llvm::make_unique<Environment>(Code, FileName, Ranges, FirstStartColumn,
2207                                      NextStartColumn, LastStartColumn);
2208   llvm::Optional<std::string> CurrentCode = None;
2209   tooling::Replacements Fixes;
2210   unsigned Penalty = 0;
2211   for (size_t I = 0, E = Passes.size(); I < E; ++I) {
2212     std::pair<tooling::Replacements, unsigned> PassFixes = Passes[I](*Env);
2213     auto NewCode = applyAllReplacements(
2214         CurrentCode ? StringRef(*CurrentCode) : Code, PassFixes.first);
2215     if (NewCode) {
2216       Fixes = Fixes.merge(PassFixes.first);
2217       Penalty += PassFixes.second;
2218       if (I + 1 < E) {
2219         CurrentCode = std::move(*NewCode);
2220         Env = llvm::make_unique<Environment>(
2221             *CurrentCode, FileName,
2222             tooling::calculateRangesAfterReplacements(Fixes, Ranges),
2223             FirstStartColumn, NextStartColumn, LastStartColumn);
2224       }
2225     }
2226   }
2227 
2228   return {Fixes, Penalty};
2229 }
2230 } // namespace internal
2231 
2232 tooling::Replacements reformat(const FormatStyle &Style, StringRef Code,
2233                                ArrayRef<tooling::Range> Ranges,
2234                                StringRef FileName,
2235                                FormattingAttemptStatus *Status) {
2236   return internal::reformat(Style, Code, Ranges,
2237                             /*FirstStartColumn=*/0,
2238                             /*NextStartColumn=*/0,
2239                             /*LastStartColumn=*/0, FileName, Status)
2240       .first;
2241 }
2242 
2243 tooling::Replacements cleanup(const FormatStyle &Style, StringRef Code,
2244                               ArrayRef<tooling::Range> Ranges,
2245                               StringRef FileName) {
2246   // cleanups only apply to C++ (they mostly concern ctor commas etc.)
2247   if (Style.Language != FormatStyle::LK_Cpp)
2248     return tooling::Replacements();
2249   return Cleaner(Environment(Code, FileName, Ranges), Style).process().first;
2250 }
2251 
2252 tooling::Replacements reformat(const FormatStyle &Style, StringRef Code,
2253                                ArrayRef<tooling::Range> Ranges,
2254                                StringRef FileName, bool *IncompleteFormat) {
2255   FormattingAttemptStatus Status;
2256   auto Result = reformat(Style, Code, Ranges, FileName, &Status);
2257   if (!Status.FormatComplete)
2258     *IncompleteFormat = true;
2259   return Result;
2260 }
2261 
2262 tooling::Replacements fixNamespaceEndComments(const FormatStyle &Style,
2263                                               StringRef Code,
2264                                               ArrayRef<tooling::Range> Ranges,
2265                                               StringRef FileName) {
2266   return NamespaceEndCommentsFixer(Environment(Code, FileName, Ranges), Style)
2267       .process()
2268       .first;
2269 }
2270 
2271 tooling::Replacements sortUsingDeclarations(const FormatStyle &Style,
2272                                             StringRef Code,
2273                                             ArrayRef<tooling::Range> Ranges,
2274                                             StringRef FileName) {
2275   return UsingDeclarationsSorter(Environment(Code, FileName, Ranges), Style)
2276       .process()
2277       .first;
2278 }
2279 
2280 LangOptions getFormattingLangOpts(const FormatStyle &Style) {
2281   LangOptions LangOpts;
2282   LangOpts.CPlusPlus = 1;
2283   LangOpts.CPlusPlus11 = Style.Standard == FormatStyle::LS_Cpp03 ? 0 : 1;
2284   LangOpts.CPlusPlus14 = Style.Standard == FormatStyle::LS_Cpp03 ? 0 : 1;
2285   LangOpts.CPlusPlus17 = Style.Standard == FormatStyle::LS_Cpp03 ? 0 : 1;
2286   LangOpts.CPlusPlus2a = Style.Standard == FormatStyle::LS_Cpp03 ? 0 : 1;
2287   LangOpts.LineComment = 1;
2288   bool AlternativeOperators = Style.isCpp();
2289   LangOpts.CXXOperatorNames = AlternativeOperators ? 1 : 0;
2290   LangOpts.Bool = 1;
2291   LangOpts.ObjC = 1;
2292   LangOpts.MicrosoftExt = 1;    // To get kw___try, kw___finally.
2293   LangOpts.DeclSpecKeyword = 1; // To get __declspec.
2294   return LangOpts;
2295 }
2296 
2297 const char *StyleOptionHelpDescription =
2298     "Coding style, currently supports:\n"
2299     "  LLVM, Google, Chromium, Mozilla, WebKit.\n"
2300     "Use -style=file to load style configuration from\n"
2301     ".clang-format file located in one of the parent\n"
2302     "directories of the source file (or current\n"
2303     "directory for stdin).\n"
2304     "Use -style=\"{key: value, ...}\" to set specific\n"
2305     "parameters, e.g.:\n"
2306     "  -style=\"{BasedOnStyle: llvm, IndentWidth: 8}\"";
2307 
2308 static FormatStyle::LanguageKind getLanguageByFileName(StringRef FileName) {
2309   if (FileName.endswith(".java"))
2310     return FormatStyle::LK_Java;
2311   if (FileName.endswith_lower(".js") || FileName.endswith_lower(".ts"))
2312     return FormatStyle::LK_JavaScript; // JavaScript or TypeScript.
2313   if (FileName.endswith(".m") || FileName.endswith(".mm"))
2314     return FormatStyle::LK_ObjC;
2315   if (FileName.endswith_lower(".proto") ||
2316       FileName.endswith_lower(".protodevel"))
2317     return FormatStyle::LK_Proto;
2318   if (FileName.endswith_lower(".textpb") ||
2319       FileName.endswith_lower(".pb.txt") ||
2320       FileName.endswith_lower(".textproto") ||
2321       FileName.endswith_lower(".asciipb"))
2322     return FormatStyle::LK_TextProto;
2323   if (FileName.endswith_lower(".td"))
2324     return FormatStyle::LK_TableGen;
2325   return FormatStyle::LK_Cpp;
2326 }
2327 
2328 FormatStyle::LanguageKind guessLanguage(StringRef FileName, StringRef Code) {
2329   const auto GuessedLanguage = getLanguageByFileName(FileName);
2330   if (GuessedLanguage == FormatStyle::LK_Cpp) {
2331     auto Extension = llvm::sys::path::extension(FileName);
2332     // If there's no file extension (or it's .h), we need to check the contents
2333     // of the code to see if it contains Objective-C.
2334     if (Extension.empty() || Extension == ".h") {
2335       auto NonEmptyFileName = FileName.empty() ? "guess.h" : FileName;
2336       Environment Env(Code, NonEmptyFileName, /*Ranges=*/{});
2337       ObjCHeaderStyleGuesser Guesser(Env, getLLVMStyle());
2338       Guesser.process();
2339       if (Guesser.isObjC())
2340         return FormatStyle::LK_ObjC;
2341     }
2342   }
2343   return GuessedLanguage;
2344 }
2345 
2346 const char *DefaultFormatStyle = "file";
2347 
2348 const char *DefaultFallbackStyle = "LLVM";
2349 
2350 llvm::Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName,
2351                                      StringRef FallbackStyleName,
2352                                      StringRef Code,
2353                                      llvm::vfs::FileSystem *FS) {
2354   if (!FS) {
2355     FS = llvm::vfs::getRealFileSystem().get();
2356   }
2357   FormatStyle Style = getLLVMStyle(guessLanguage(FileName, Code));
2358 
2359   FormatStyle FallbackStyle = getNoStyle();
2360   if (!getPredefinedStyle(FallbackStyleName, Style.Language, &FallbackStyle))
2361     return make_string_error("Invalid fallback style \"" + FallbackStyleName);
2362 
2363   if (StyleName.startswith("{")) {
2364     // Parse YAML/JSON style from the command line.
2365     if (std::error_code ec = parseConfiguration(StyleName, &Style))
2366       return make_string_error("Error parsing -style: " + ec.message());
2367     return Style;
2368   }
2369 
2370   if (!StyleName.equals_lower("file")) {
2371     if (!getPredefinedStyle(StyleName, Style.Language, &Style))
2372       return make_string_error("Invalid value for -style");
2373     return Style;
2374   }
2375 
2376   // Look for .clang-format/_clang-format file in the file's parent directories.
2377   SmallString<128> UnsuitableConfigFiles;
2378   SmallString<128> Path(FileName);
2379   if (std::error_code EC = FS->makeAbsolute(Path))
2380     return make_string_error(EC.message());
2381 
2382   for (StringRef Directory = Path; !Directory.empty();
2383        Directory = llvm::sys::path::parent_path(Directory)) {
2384 
2385     auto Status = FS->status(Directory);
2386     if (!Status ||
2387         Status->getType() != llvm::sys::fs::file_type::directory_file) {
2388       continue;
2389     }
2390 
2391     SmallString<128> ConfigFile(Directory);
2392 
2393     llvm::sys::path::append(ConfigFile, ".clang-format");
2394     LLVM_DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n");
2395 
2396     Status = FS->status(ConfigFile.str());
2397     bool FoundConfigFile =
2398         Status && (Status->getType() == llvm::sys::fs::file_type::regular_file);
2399     if (!FoundConfigFile) {
2400       // Try _clang-format too, since dotfiles are not commonly used on Windows.
2401       ConfigFile = Directory;
2402       llvm::sys::path::append(ConfigFile, "_clang-format");
2403       LLVM_DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n");
2404       Status = FS->status(ConfigFile.str());
2405       FoundConfigFile = Status && (Status->getType() ==
2406                                    llvm::sys::fs::file_type::regular_file);
2407     }
2408 
2409     if (FoundConfigFile) {
2410       llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
2411           FS->getBufferForFile(ConfigFile.str());
2412       if (std::error_code EC = Text.getError())
2413         return make_string_error(EC.message());
2414       if (std::error_code ec =
2415               parseConfiguration(Text.get()->getBuffer(), &Style)) {
2416         if (ec == ParseError::Unsuitable) {
2417           if (!UnsuitableConfigFiles.empty())
2418             UnsuitableConfigFiles.append(", ");
2419           UnsuitableConfigFiles.append(ConfigFile);
2420           continue;
2421         }
2422         return make_string_error("Error reading " + ConfigFile + ": " +
2423                                  ec.message());
2424       }
2425       LLVM_DEBUG(llvm::dbgs()
2426                  << "Using configuration file " << ConfigFile << "\n");
2427       return Style;
2428     }
2429   }
2430   if (!UnsuitableConfigFiles.empty())
2431     return make_string_error("Configuration file(s) do(es) not support " +
2432                              getLanguageName(Style.Language) + ": " +
2433                              UnsuitableConfigFiles);
2434   return FallbackStyle;
2435 }
2436 
2437 } // namespace format
2438 } // namespace clang
2439