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 "BreakableToken.h"
18 #include "ContinuationIndenter.h"
19 #include "FormatInternal.h"
20 #include "FormatTokenLexer.h"
21 #include "NamespaceEndCommentsFixer.h"
22 #include "SortJavaScriptImports.h"
23 #include "TokenAnalyzer.h"
24 #include "TokenAnnotator.h"
25 #include "UnwrappedLineFormatter.h"
26 #include "UnwrappedLineParser.h"
27 #include "UsingDeclarationsSorter.h"
28 #include "WhitespaceManager.h"
29 #include "clang/Basic/Diagnostic.h"
30 #include "clang/Basic/DiagnosticOptions.h"
31 #include "clang/Basic/SourceManager.h"
32 #include "clang/Lex/Lexer.h"
33 #include "clang/Tooling/Inclusions/HeaderIncludes.h"
34 #include "llvm/ADT/STLExtras.h"
35 #include "llvm/ADT/StringRef.h"
36 #include "llvm/Support/Allocator.h"
37 #include "llvm/Support/Debug.h"
38 #include "llvm/Support/Path.h"
39 #include "llvm/Support/Regex.h"
40 #include "llvm/Support/VirtualFileSystem.h"
41 #include "llvm/Support/YAMLTraits.h"
42 #include <algorithm>
43 #include <memory>
44 #include <mutex>
45 #include <string>
46 #include <unordered_map>
47 
48 #define DEBUG_TYPE "format-formatter"
49 
50 using clang::format::FormatStyle;
51 
52 LLVM_YAML_IS_SEQUENCE_VECTOR(clang::format::FormatStyle::RawStringFormat)
53 
54 namespace llvm {
55 namespace yaml {
56 template <> struct ScalarEnumerationTraits<FormatStyle::LanguageKind> {
57   static void enumeration(IO &IO, FormatStyle::LanguageKind &Value) {
58     IO.enumCase(Value, "Cpp", FormatStyle::LK_Cpp);
59     IO.enumCase(Value, "Java", FormatStyle::LK_Java);
60     IO.enumCase(Value, "JavaScript", FormatStyle::LK_JavaScript);
61     IO.enumCase(Value, "ObjC", FormatStyle::LK_ObjC);
62     IO.enumCase(Value, "Proto", FormatStyle::LK_Proto);
63     IO.enumCase(Value, "TableGen", FormatStyle::LK_TableGen);
64     IO.enumCase(Value, "TextProto", FormatStyle::LK_TextProto);
65     IO.enumCase(Value, "CSharp", FormatStyle::LK_CSharp);
66   }
67 };
68 
69 template <> struct ScalarEnumerationTraits<FormatStyle::LanguageStandard> {
70   static void enumeration(IO &IO, FormatStyle::LanguageStandard &Value) {
71     IO.enumCase(Value, "c++03", FormatStyle::LS_Cpp03);
72     IO.enumCase(Value, "C++03", FormatStyle::LS_Cpp03); // Legacy alias
73     IO.enumCase(Value, "Cpp03", FormatStyle::LS_Cpp03); // Legacy alias
74 
75     IO.enumCase(Value, "c++11", FormatStyle::LS_Cpp11);
76     IO.enumCase(Value, "C++11", FormatStyle::LS_Cpp11); // Legacy alias
77 
78     IO.enumCase(Value, "c++14", FormatStyle::LS_Cpp14);
79     IO.enumCase(Value, "c++17", FormatStyle::LS_Cpp17);
80     IO.enumCase(Value, "c++20", FormatStyle::LS_Cpp20);
81 
82     IO.enumCase(Value, "Latest", FormatStyle::LS_Latest);
83     IO.enumCase(Value, "Cpp11", FormatStyle::LS_Latest); // Legacy alias
84     IO.enumCase(Value, "Auto", FormatStyle::LS_Auto);
85   }
86 };
87 
88 template <> struct ScalarEnumerationTraits<FormatStyle::UseTabStyle> {
89   static void enumeration(IO &IO, FormatStyle::UseTabStyle &Value) {
90     IO.enumCase(Value, "Never", FormatStyle::UT_Never);
91     IO.enumCase(Value, "false", FormatStyle::UT_Never);
92     IO.enumCase(Value, "Always", FormatStyle::UT_Always);
93     IO.enumCase(Value, "true", FormatStyle::UT_Always);
94     IO.enumCase(Value, "ForIndentation", FormatStyle::UT_ForIndentation);
95     IO.enumCase(Value, "ForContinuationAndIndentation",
96                 FormatStyle::UT_ForContinuationAndIndentation);
97     IO.enumCase(Value, "AlignWithSpaces", FormatStyle::UT_AlignWithSpaces);
98   }
99 };
100 
101 template <> struct ScalarEnumerationTraits<FormatStyle::JavaScriptQuoteStyle> {
102   static void enumeration(IO &IO, FormatStyle::JavaScriptQuoteStyle &Value) {
103     IO.enumCase(Value, "Leave", FormatStyle::JSQS_Leave);
104     IO.enumCase(Value, "Single", FormatStyle::JSQS_Single);
105     IO.enumCase(Value, "Double", FormatStyle::JSQS_Double);
106   }
107 };
108 
109 template <> struct ScalarEnumerationTraits<FormatStyle::ShortBlockStyle> {
110   static void enumeration(IO &IO, FormatStyle::ShortBlockStyle &Value) {
111     IO.enumCase(Value, "Never", FormatStyle::SBS_Never);
112     IO.enumCase(Value, "false", FormatStyle::SBS_Never);
113     IO.enumCase(Value, "Always", FormatStyle::SBS_Always);
114     IO.enumCase(Value, "true", FormatStyle::SBS_Always);
115     IO.enumCase(Value, "Empty", FormatStyle::SBS_Empty);
116   }
117 };
118 
119 template <> struct ScalarEnumerationTraits<FormatStyle::ShortFunctionStyle> {
120   static void enumeration(IO &IO, FormatStyle::ShortFunctionStyle &Value) {
121     IO.enumCase(Value, "None", FormatStyle::SFS_None);
122     IO.enumCase(Value, "false", FormatStyle::SFS_None);
123     IO.enumCase(Value, "All", FormatStyle::SFS_All);
124     IO.enumCase(Value, "true", FormatStyle::SFS_All);
125     IO.enumCase(Value, "Inline", FormatStyle::SFS_Inline);
126     IO.enumCase(Value, "InlineOnly", FormatStyle::SFS_InlineOnly);
127     IO.enumCase(Value, "Empty", FormatStyle::SFS_Empty);
128   }
129 };
130 
131 template <> struct ScalarEnumerationTraits<FormatStyle::AlignConsecutiveStyle> {
132   static void enumeration(IO &IO, FormatStyle::AlignConsecutiveStyle &Value) {
133     IO.enumCase(Value, "None", FormatStyle::ACS_None);
134     IO.enumCase(Value, "Consecutive", FormatStyle::ACS_Consecutive);
135     IO.enumCase(Value, "AcrossEmptyLines", FormatStyle::ACS_AcrossEmptyLines);
136     IO.enumCase(Value, "AcrossComments", FormatStyle::ACS_AcrossComments);
137     IO.enumCase(Value, "AcrossEmptyLinesAndComments",
138                 FormatStyle::ACS_AcrossEmptyLinesAndComments);
139 
140     // For backward compability.
141     IO.enumCase(Value, "true", FormatStyle::ACS_Consecutive);
142     IO.enumCase(Value, "false", FormatStyle::ACS_None);
143   }
144 };
145 
146 template <> struct ScalarEnumerationTraits<FormatStyle::ShortIfStyle> {
147   static void enumeration(IO &IO, FormatStyle::ShortIfStyle &Value) {
148     IO.enumCase(Value, "Never", FormatStyle::SIS_Never);
149     IO.enumCase(Value, "WithoutElse", FormatStyle::SIS_WithoutElse);
150     IO.enumCase(Value, "OnlyFirstIf", FormatStyle::SIS_OnlyFirstIf);
151     IO.enumCase(Value, "AllIfsAndElse", FormatStyle::SIS_AllIfsAndElse);
152 
153     // For backward compatibility.
154     IO.enumCase(Value, "Always", FormatStyle::SIS_OnlyFirstIf);
155     IO.enumCase(Value, "false", FormatStyle::SIS_Never);
156     IO.enumCase(Value, "true", FormatStyle::SIS_WithoutElse);
157   }
158 };
159 
160 template <> struct ScalarEnumerationTraits<FormatStyle::ShortLambdaStyle> {
161   static void enumeration(IO &IO, FormatStyle::ShortLambdaStyle &Value) {
162     IO.enumCase(Value, "None", FormatStyle::SLS_None);
163     IO.enumCase(Value, "false", FormatStyle::SLS_None);
164     IO.enumCase(Value, "Empty", FormatStyle::SLS_Empty);
165     IO.enumCase(Value, "Inline", FormatStyle::SLS_Inline);
166     IO.enumCase(Value, "All", FormatStyle::SLS_All);
167     IO.enumCase(Value, "true", FormatStyle::SLS_All);
168   }
169 };
170 
171 template <> struct ScalarEnumerationTraits<FormatStyle::BinPackStyle> {
172   static void enumeration(IO &IO, FormatStyle::BinPackStyle &Value) {
173     IO.enumCase(Value, "Auto", FormatStyle::BPS_Auto);
174     IO.enumCase(Value, "Always", FormatStyle::BPS_Always);
175     IO.enumCase(Value, "Never", FormatStyle::BPS_Never);
176   }
177 };
178 
179 template <> struct ScalarEnumerationTraits<FormatStyle::TrailingCommaStyle> {
180   static void enumeration(IO &IO, FormatStyle::TrailingCommaStyle &Value) {
181     IO.enumCase(Value, "None", FormatStyle::TCS_None);
182     IO.enumCase(Value, "Wrapped", FormatStyle::TCS_Wrapped);
183   }
184 };
185 
186 template <> struct ScalarEnumerationTraits<FormatStyle::BinaryOperatorStyle> {
187   static void enumeration(IO &IO, FormatStyle::BinaryOperatorStyle &Value) {
188     IO.enumCase(Value, "All", FormatStyle::BOS_All);
189     IO.enumCase(Value, "true", FormatStyle::BOS_All);
190     IO.enumCase(Value, "None", FormatStyle::BOS_None);
191     IO.enumCase(Value, "false", FormatStyle::BOS_None);
192     IO.enumCase(Value, "NonAssignment", FormatStyle::BOS_NonAssignment);
193   }
194 };
195 
196 template <> struct ScalarEnumerationTraits<FormatStyle::BraceBreakingStyle> {
197   static void enumeration(IO &IO, FormatStyle::BraceBreakingStyle &Value) {
198     IO.enumCase(Value, "Attach", FormatStyle::BS_Attach);
199     IO.enumCase(Value, "Linux", FormatStyle::BS_Linux);
200     IO.enumCase(Value, "Mozilla", FormatStyle::BS_Mozilla);
201     IO.enumCase(Value, "Stroustrup", FormatStyle::BS_Stroustrup);
202     IO.enumCase(Value, "Allman", FormatStyle::BS_Allman);
203     IO.enumCase(Value, "Whitesmiths", FormatStyle::BS_Whitesmiths);
204     IO.enumCase(Value, "GNU", FormatStyle::BS_GNU);
205     IO.enumCase(Value, "WebKit", FormatStyle::BS_WebKit);
206     IO.enumCase(Value, "Custom", FormatStyle::BS_Custom);
207   }
208 };
209 
210 template <>
211 struct ScalarEnumerationTraits<
212     FormatStyle::BraceWrappingAfterControlStatementStyle> {
213   static void
214   enumeration(IO &IO,
215               FormatStyle::BraceWrappingAfterControlStatementStyle &Value) {
216     IO.enumCase(Value, "Never", FormatStyle::BWACS_Never);
217     IO.enumCase(Value, "MultiLine", FormatStyle::BWACS_MultiLine);
218     IO.enumCase(Value, "Always", FormatStyle::BWACS_Always);
219 
220     // For backward compatibility.
221     IO.enumCase(Value, "false", FormatStyle::BWACS_Never);
222     IO.enumCase(Value, "true", FormatStyle::BWACS_Always);
223   }
224 };
225 
226 template <>
227 struct ScalarEnumerationTraits<FormatStyle::BreakConstructorInitializersStyle> {
228   static void
229   enumeration(IO &IO, FormatStyle::BreakConstructorInitializersStyle &Value) {
230     IO.enumCase(Value, "BeforeColon", FormatStyle::BCIS_BeforeColon);
231     IO.enumCase(Value, "BeforeComma", FormatStyle::BCIS_BeforeComma);
232     IO.enumCase(Value, "AfterColon", FormatStyle::BCIS_AfterColon);
233   }
234 };
235 
236 template <>
237 struct ScalarEnumerationTraits<FormatStyle::BreakInheritanceListStyle> {
238   static void enumeration(IO &IO,
239                           FormatStyle::BreakInheritanceListStyle &Value) {
240     IO.enumCase(Value, "BeforeColon", FormatStyle::BILS_BeforeColon);
241     IO.enumCase(Value, "BeforeComma", FormatStyle::BILS_BeforeComma);
242     IO.enumCase(Value, "AfterColon", FormatStyle::BILS_AfterColon);
243     IO.enumCase(Value, "AfterComma", FormatStyle::BILS_AfterComma);
244   }
245 };
246 
247 template <>
248 struct ScalarEnumerationTraits<FormatStyle::EmptyLineAfterAccessModifierStyle> {
249   static void
250   enumeration(IO &IO, FormatStyle::EmptyLineAfterAccessModifierStyle &Value) {
251     IO.enumCase(Value, "Never", FormatStyle::ELAAMS_Never);
252     IO.enumCase(Value, "Leave", FormatStyle::ELAAMS_Leave);
253     IO.enumCase(Value, "Always", FormatStyle::ELAAMS_Always);
254   }
255 };
256 
257 template <>
258 struct ScalarEnumerationTraits<
259     FormatStyle::EmptyLineBeforeAccessModifierStyle> {
260   static void
261   enumeration(IO &IO, FormatStyle::EmptyLineBeforeAccessModifierStyle &Value) {
262     IO.enumCase(Value, "Never", FormatStyle::ELBAMS_Never);
263     IO.enumCase(Value, "Leave", FormatStyle::ELBAMS_Leave);
264     IO.enumCase(Value, "LogicalBlock", FormatStyle::ELBAMS_LogicalBlock);
265     IO.enumCase(Value, "Always", FormatStyle::ELBAMS_Always);
266   }
267 };
268 
269 template <>
270 struct ScalarEnumerationTraits<FormatStyle::PPDirectiveIndentStyle> {
271   static void enumeration(IO &IO, FormatStyle::PPDirectiveIndentStyle &Value) {
272     IO.enumCase(Value, "None", FormatStyle::PPDIS_None);
273     IO.enumCase(Value, "AfterHash", FormatStyle::PPDIS_AfterHash);
274     IO.enumCase(Value, "BeforeHash", FormatStyle::PPDIS_BeforeHash);
275   }
276 };
277 
278 template <>
279 struct ScalarEnumerationTraits<FormatStyle::IndentExternBlockStyle> {
280   static void enumeration(IO &IO, FormatStyle::IndentExternBlockStyle &Value) {
281     IO.enumCase(Value, "AfterExternBlock", FormatStyle::IEBS_AfterExternBlock);
282     IO.enumCase(Value, "Indent", FormatStyle::IEBS_Indent);
283     IO.enumCase(Value, "NoIndent", FormatStyle::IEBS_NoIndent);
284     IO.enumCase(Value, "true", FormatStyle::IEBS_Indent);
285     IO.enumCase(Value, "false", FormatStyle::IEBS_NoIndent);
286   }
287 };
288 
289 template <>
290 struct ScalarEnumerationTraits<FormatStyle::ReturnTypeBreakingStyle> {
291   static void enumeration(IO &IO, FormatStyle::ReturnTypeBreakingStyle &Value) {
292     IO.enumCase(Value, "None", FormatStyle::RTBS_None);
293     IO.enumCase(Value, "All", FormatStyle::RTBS_All);
294     IO.enumCase(Value, "TopLevel", FormatStyle::RTBS_TopLevel);
295     IO.enumCase(Value, "TopLevelDefinitions",
296                 FormatStyle::RTBS_TopLevelDefinitions);
297     IO.enumCase(Value, "AllDefinitions", FormatStyle::RTBS_AllDefinitions);
298   }
299 };
300 
301 template <>
302 struct ScalarEnumerationTraits<FormatStyle::BreakTemplateDeclarationsStyle> {
303   static void enumeration(IO &IO,
304                           FormatStyle::BreakTemplateDeclarationsStyle &Value) {
305     IO.enumCase(Value, "No", FormatStyle::BTDS_No);
306     IO.enumCase(Value, "MultiLine", FormatStyle::BTDS_MultiLine);
307     IO.enumCase(Value, "Yes", FormatStyle::BTDS_Yes);
308 
309     // For backward compatibility.
310     IO.enumCase(Value, "false", FormatStyle::BTDS_MultiLine);
311     IO.enumCase(Value, "true", FormatStyle::BTDS_Yes);
312   }
313 };
314 
315 template <>
316 struct ScalarEnumerationTraits<FormatStyle::DefinitionReturnTypeBreakingStyle> {
317   static void
318   enumeration(IO &IO, FormatStyle::DefinitionReturnTypeBreakingStyle &Value) {
319     IO.enumCase(Value, "None", FormatStyle::DRTBS_None);
320     IO.enumCase(Value, "All", FormatStyle::DRTBS_All);
321     IO.enumCase(Value, "TopLevel", FormatStyle::DRTBS_TopLevel);
322 
323     // For backward compatibility.
324     IO.enumCase(Value, "false", FormatStyle::DRTBS_None);
325     IO.enumCase(Value, "true", FormatStyle::DRTBS_All);
326   }
327 };
328 
329 template <>
330 struct ScalarEnumerationTraits<FormatStyle::NamespaceIndentationKind> {
331   static void enumeration(IO &IO,
332                           FormatStyle::NamespaceIndentationKind &Value) {
333     IO.enumCase(Value, "None", FormatStyle::NI_None);
334     IO.enumCase(Value, "Inner", FormatStyle::NI_Inner);
335     IO.enumCase(Value, "All", FormatStyle::NI_All);
336   }
337 };
338 
339 template <> struct ScalarEnumerationTraits<FormatStyle::BracketAlignmentStyle> {
340   static void enumeration(IO &IO, FormatStyle::BracketAlignmentStyle &Value) {
341     IO.enumCase(Value, "Align", FormatStyle::BAS_Align);
342     IO.enumCase(Value, "DontAlign", FormatStyle::BAS_DontAlign);
343     IO.enumCase(Value, "AlwaysBreak", FormatStyle::BAS_AlwaysBreak);
344 
345     // For backward compatibility.
346     IO.enumCase(Value, "true", FormatStyle::BAS_Align);
347     IO.enumCase(Value, "false", FormatStyle::BAS_DontAlign);
348   }
349 };
350 
351 template <>
352 struct ScalarEnumerationTraits<FormatStyle::EscapedNewlineAlignmentStyle> {
353   static void enumeration(IO &IO,
354                           FormatStyle::EscapedNewlineAlignmentStyle &Value) {
355     IO.enumCase(Value, "DontAlign", FormatStyle::ENAS_DontAlign);
356     IO.enumCase(Value, "Left", FormatStyle::ENAS_Left);
357     IO.enumCase(Value, "Right", FormatStyle::ENAS_Right);
358 
359     // For backward compatibility.
360     IO.enumCase(Value, "true", FormatStyle::ENAS_Left);
361     IO.enumCase(Value, "false", FormatStyle::ENAS_Right);
362   }
363 };
364 
365 template <> struct ScalarEnumerationTraits<FormatStyle::OperandAlignmentStyle> {
366   static void enumeration(IO &IO, FormatStyle::OperandAlignmentStyle &Value) {
367     IO.enumCase(Value, "DontAlign", FormatStyle::OAS_DontAlign);
368     IO.enumCase(Value, "Align", FormatStyle::OAS_Align);
369     IO.enumCase(Value, "AlignAfterOperator",
370                 FormatStyle::OAS_AlignAfterOperator);
371 
372     // For backward compatibility.
373     IO.enumCase(Value, "true", FormatStyle::OAS_Align);
374     IO.enumCase(Value, "false", FormatStyle::OAS_DontAlign);
375   }
376 };
377 
378 template <> struct ScalarEnumerationTraits<FormatStyle::PointerAlignmentStyle> {
379   static void enumeration(IO &IO, FormatStyle::PointerAlignmentStyle &Value) {
380     IO.enumCase(Value, "Middle", FormatStyle::PAS_Middle);
381     IO.enumCase(Value, "Left", FormatStyle::PAS_Left);
382     IO.enumCase(Value, "Right", FormatStyle::PAS_Right);
383 
384     // For backward compatibility.
385     IO.enumCase(Value, "true", FormatStyle::PAS_Left);
386     IO.enumCase(Value, "false", FormatStyle::PAS_Right);
387   }
388 };
389 
390 template <>
391 struct ScalarEnumerationTraits<FormatStyle::SpaceAroundPointerQualifiersStyle> {
392   static void
393   enumeration(IO &IO, FormatStyle::SpaceAroundPointerQualifiersStyle &Value) {
394     IO.enumCase(Value, "Default", FormatStyle::SAPQ_Default);
395     IO.enumCase(Value, "Before", FormatStyle::SAPQ_Before);
396     IO.enumCase(Value, "After", FormatStyle::SAPQ_After);
397     IO.enumCase(Value, "Both", FormatStyle::SAPQ_Both);
398   }
399 };
400 
401 template <>
402 struct ScalarEnumerationTraits<FormatStyle::SpaceBeforeParensOptions> {
403   static void enumeration(IO &IO,
404                           FormatStyle::SpaceBeforeParensOptions &Value) {
405     IO.enumCase(Value, "Never", FormatStyle::SBPO_Never);
406     IO.enumCase(Value, "ControlStatements",
407                 FormatStyle::SBPO_ControlStatements);
408     IO.enumCase(Value, "ControlStatementsExceptForEachMacros",
409                 FormatStyle::SBPO_ControlStatementsExceptForEachMacros);
410     IO.enumCase(Value, "NonEmptyParentheses",
411                 FormatStyle::SBPO_NonEmptyParentheses);
412     IO.enumCase(Value, "Always", FormatStyle::SBPO_Always);
413 
414     // For backward compatibility.
415     IO.enumCase(Value, "false", FormatStyle::SBPO_Never);
416     IO.enumCase(Value, "true", FormatStyle::SBPO_ControlStatements);
417   }
418 };
419 
420 template <>
421 struct ScalarEnumerationTraits<FormatStyle::BitFieldColonSpacingStyle> {
422   static void enumeration(IO &IO,
423                           FormatStyle::BitFieldColonSpacingStyle &Value) {
424     IO.enumCase(Value, "Both", FormatStyle::BFCS_Both);
425     IO.enumCase(Value, "None", FormatStyle::BFCS_None);
426     IO.enumCase(Value, "Before", FormatStyle::BFCS_Before);
427     IO.enumCase(Value, "After", FormatStyle::BFCS_After);
428   }
429 };
430 
431 template <> struct ScalarEnumerationTraits<FormatStyle::SortIncludesOptions> {
432   static void enumeration(IO &IO, FormatStyle::SortIncludesOptions &Value) {
433     IO.enumCase(Value, "Never", FormatStyle::SI_Never);
434     IO.enumCase(Value, "CaseInsensitive", FormatStyle::SI_CaseInsensitive);
435     IO.enumCase(Value, "CaseSensitive", FormatStyle::SI_CaseSensitive);
436 
437     // For backward compatibility.
438     IO.enumCase(Value, "false", FormatStyle::SI_Never);
439     IO.enumCase(Value, "true", FormatStyle::SI_CaseSensitive);
440   }
441 };
442 
443 template <>
444 struct ScalarEnumerationTraits<FormatStyle::SortJavaStaticImportOptions> {
445   static void enumeration(IO &IO,
446                           FormatStyle::SortJavaStaticImportOptions &Value) {
447     IO.enumCase(Value, "Before", FormatStyle::SJSIO_Before);
448     IO.enumCase(Value, "After", FormatStyle::SJSIO_After);
449   }
450 };
451 
452 template <> struct ScalarEnumerationTraits<FormatStyle::SpacesInAnglesStyle> {
453   static void enumeration(IO &IO, FormatStyle::SpacesInAnglesStyle &Value) {
454     IO.enumCase(Value, "Never", FormatStyle::SIAS_Never);
455     IO.enumCase(Value, "Always", FormatStyle::SIAS_Always);
456     IO.enumCase(Value, "Leave", FormatStyle::SIAS_Leave);
457 
458     // For backward compatibility.
459     IO.enumCase(Value, "false", FormatStyle::SIAS_Never);
460     IO.enumCase(Value, "true", FormatStyle::SIAS_Always);
461   }
462 };
463 
464 template <> struct MappingTraits<FormatStyle> {
465   static void mapping(IO &IO, FormatStyle &Style) {
466     // When reading, read the language first, we need it for getPredefinedStyle.
467     IO.mapOptional("Language", Style.Language);
468 
469     if (IO.outputting()) {
470       StringRef StylesArray[] = {"LLVM",   "Google", "Chromium", "Mozilla",
471                                  "WebKit", "GNU",    "Microsoft"};
472       ArrayRef<StringRef> Styles(StylesArray);
473       for (size_t i = 0, e = Styles.size(); i < e; ++i) {
474         StringRef StyleName(Styles[i]);
475         FormatStyle PredefinedStyle;
476         if (getPredefinedStyle(StyleName, Style.Language, &PredefinedStyle) &&
477             Style == PredefinedStyle) {
478           IO.mapOptional("# BasedOnStyle", StyleName);
479           break;
480         }
481       }
482     } else {
483       StringRef BasedOnStyle;
484       IO.mapOptional("BasedOnStyle", BasedOnStyle);
485       if (!BasedOnStyle.empty()) {
486         FormatStyle::LanguageKind OldLanguage = Style.Language;
487         FormatStyle::LanguageKind Language =
488             ((FormatStyle *)IO.getContext())->Language;
489         if (!getPredefinedStyle(BasedOnStyle, Language, &Style)) {
490           IO.setError(Twine("Unknown value for BasedOnStyle: ", BasedOnStyle));
491           return;
492         }
493         Style.Language = OldLanguage;
494       }
495     }
496 
497     // For backward compatibility.
498     if (!IO.outputting()) {
499       IO.mapOptional("AlignEscapedNewlinesLeft", Style.AlignEscapedNewlines);
500       IO.mapOptional("DerivePointerBinding", Style.DerivePointerAlignment);
501       IO.mapOptional("IndentFunctionDeclarationAfterType",
502                      Style.IndentWrappedFunctionNames);
503       IO.mapOptional("PointerBindsToType", Style.PointerAlignment);
504       IO.mapOptional("SpaceAfterControlStatementKeyword",
505                      Style.SpaceBeforeParens);
506     }
507 
508     IO.mapOptional("AccessModifierOffset", Style.AccessModifierOffset);
509     IO.mapOptional("AlignAfterOpenBracket", Style.AlignAfterOpenBracket);
510     IO.mapOptional("AlignConsecutiveMacros", Style.AlignConsecutiveMacros);
511     IO.mapOptional("AlignConsecutiveAssignments",
512                    Style.AlignConsecutiveAssignments);
513     IO.mapOptional("AlignConsecutiveBitFields",
514                    Style.AlignConsecutiveBitFields);
515     IO.mapOptional("AlignConsecutiveDeclarations",
516                    Style.AlignConsecutiveDeclarations);
517     IO.mapOptional("AlignEscapedNewlines", Style.AlignEscapedNewlines);
518     IO.mapOptional("AlignOperands", Style.AlignOperands);
519     IO.mapOptional("AlignTrailingComments", Style.AlignTrailingComments);
520     IO.mapOptional("AllowAllArgumentsOnNextLine",
521                    Style.AllowAllArgumentsOnNextLine);
522     IO.mapOptional("AllowAllConstructorInitializersOnNextLine",
523                    Style.AllowAllConstructorInitializersOnNextLine);
524     IO.mapOptional("AllowAllParametersOfDeclarationOnNextLine",
525                    Style.AllowAllParametersOfDeclarationOnNextLine);
526     IO.mapOptional("AllowShortEnumsOnASingleLine",
527                    Style.AllowShortEnumsOnASingleLine);
528     IO.mapOptional("AllowShortBlocksOnASingleLine",
529                    Style.AllowShortBlocksOnASingleLine);
530     IO.mapOptional("AllowShortCaseLabelsOnASingleLine",
531                    Style.AllowShortCaseLabelsOnASingleLine);
532     IO.mapOptional("AllowShortFunctionsOnASingleLine",
533                    Style.AllowShortFunctionsOnASingleLine);
534     IO.mapOptional("AllowShortLambdasOnASingleLine",
535                    Style.AllowShortLambdasOnASingleLine);
536     IO.mapOptional("AllowShortIfStatementsOnASingleLine",
537                    Style.AllowShortIfStatementsOnASingleLine);
538     IO.mapOptional("AllowShortLoopsOnASingleLine",
539                    Style.AllowShortLoopsOnASingleLine);
540     IO.mapOptional("AlwaysBreakAfterDefinitionReturnType",
541                    Style.AlwaysBreakAfterDefinitionReturnType);
542     IO.mapOptional("AlwaysBreakAfterReturnType",
543                    Style.AlwaysBreakAfterReturnType);
544 
545     // If AlwaysBreakAfterDefinitionReturnType was specified but
546     // AlwaysBreakAfterReturnType was not, initialize the latter from the
547     // former for backwards compatibility.
548     if (Style.AlwaysBreakAfterDefinitionReturnType != FormatStyle::DRTBS_None &&
549         Style.AlwaysBreakAfterReturnType == FormatStyle::RTBS_None) {
550       if (Style.AlwaysBreakAfterDefinitionReturnType == FormatStyle::DRTBS_All)
551         Style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_AllDefinitions;
552       else if (Style.AlwaysBreakAfterDefinitionReturnType ==
553                FormatStyle::DRTBS_TopLevel)
554         Style.AlwaysBreakAfterReturnType =
555             FormatStyle::RTBS_TopLevelDefinitions;
556     }
557 
558     IO.mapOptional("AlwaysBreakBeforeMultilineStrings",
559                    Style.AlwaysBreakBeforeMultilineStrings);
560     IO.mapOptional("AlwaysBreakTemplateDeclarations",
561                    Style.AlwaysBreakTemplateDeclarations);
562     IO.mapOptional("AttributeMacros", Style.AttributeMacros);
563     IO.mapOptional("BinPackArguments", Style.BinPackArguments);
564     IO.mapOptional("BinPackParameters", Style.BinPackParameters);
565     IO.mapOptional("BraceWrapping", Style.BraceWrapping);
566     IO.mapOptional("BreakBeforeBinaryOperators",
567                    Style.BreakBeforeBinaryOperators);
568     IO.mapOptional("BreakBeforeConceptDeclarations",
569                    Style.BreakBeforeConceptDeclarations);
570     IO.mapOptional("BreakBeforeBraces", Style.BreakBeforeBraces);
571 
572     bool BreakBeforeInheritanceComma = false;
573     IO.mapOptional("BreakBeforeInheritanceComma", BreakBeforeInheritanceComma);
574     IO.mapOptional("BreakInheritanceList", Style.BreakInheritanceList);
575     // If BreakBeforeInheritanceComma was specified but
576     // BreakInheritance was not, initialize the latter from the
577     // former for backwards compatibility.
578     if (BreakBeforeInheritanceComma &&
579         Style.BreakInheritanceList == FormatStyle::BILS_BeforeColon)
580       Style.BreakInheritanceList = FormatStyle::BILS_BeforeComma;
581 
582     IO.mapOptional("BreakBeforeTernaryOperators",
583                    Style.BreakBeforeTernaryOperators);
584 
585     bool BreakConstructorInitializersBeforeComma = false;
586     IO.mapOptional("BreakConstructorInitializersBeforeComma",
587                    BreakConstructorInitializersBeforeComma);
588     IO.mapOptional("BreakConstructorInitializers",
589                    Style.BreakConstructorInitializers);
590     // If BreakConstructorInitializersBeforeComma was specified but
591     // BreakConstructorInitializers was not, initialize the latter from the
592     // former for backwards compatibility.
593     if (BreakConstructorInitializersBeforeComma &&
594         Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeColon)
595       Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma;
596 
597     IO.mapOptional("BreakAfterJavaFieldAnnotations",
598                    Style.BreakAfterJavaFieldAnnotations);
599     IO.mapOptional("BreakStringLiterals", Style.BreakStringLiterals);
600     IO.mapOptional("ColumnLimit", Style.ColumnLimit);
601     IO.mapOptional("CommentPragmas", Style.CommentPragmas);
602     IO.mapOptional("CompactNamespaces", Style.CompactNamespaces);
603     IO.mapOptional("ConstructorInitializerAllOnOneLineOrOnePerLine",
604                    Style.ConstructorInitializerAllOnOneLineOrOnePerLine);
605     IO.mapOptional("ConstructorInitializerIndentWidth",
606                    Style.ConstructorInitializerIndentWidth);
607     IO.mapOptional("ContinuationIndentWidth", Style.ContinuationIndentWidth);
608     IO.mapOptional("Cpp11BracedListStyle", Style.Cpp11BracedListStyle);
609     IO.mapOptional("DeriveLineEnding", Style.DeriveLineEnding);
610     IO.mapOptional("DerivePointerAlignment", Style.DerivePointerAlignment);
611     IO.mapOptional("DisableFormat", Style.DisableFormat);
612     IO.mapOptional("EmptyLineAfterAccessModifier",
613                    Style.EmptyLineAfterAccessModifier);
614     IO.mapOptional("EmptyLineBeforeAccessModifier",
615                    Style.EmptyLineBeforeAccessModifier);
616     IO.mapOptional("ExperimentalAutoDetectBinPacking",
617                    Style.ExperimentalAutoDetectBinPacking);
618     IO.mapOptional("FixNamespaceComments", Style.FixNamespaceComments);
619     IO.mapOptional("ForEachMacros", Style.ForEachMacros);
620     IO.mapOptional("IncludeBlocks", Style.IncludeStyle.IncludeBlocks);
621     IO.mapOptional("IncludeCategories", Style.IncludeStyle.IncludeCategories);
622     IO.mapOptional("IncludeIsMainRegex", Style.IncludeStyle.IncludeIsMainRegex);
623     IO.mapOptional("IncludeIsMainSourceRegex",
624                    Style.IncludeStyle.IncludeIsMainSourceRegex);
625     IO.mapOptional("IndentAccessModifiers", Style.IndentAccessModifiers);
626     IO.mapOptional("IndentCaseLabels", Style.IndentCaseLabels);
627     IO.mapOptional("IndentCaseBlocks", Style.IndentCaseBlocks);
628     IO.mapOptional("IndentGotoLabels", Style.IndentGotoLabels);
629     IO.mapOptional("IndentPPDirectives", Style.IndentPPDirectives);
630     IO.mapOptional("IndentExternBlock", Style.IndentExternBlock);
631     IO.mapOptional("IndentRequires", Style.IndentRequires);
632     IO.mapOptional("IndentWidth", Style.IndentWidth);
633     IO.mapOptional("IndentWrappedFunctionNames",
634                    Style.IndentWrappedFunctionNames);
635     IO.mapOptional("InsertTrailingCommas", Style.InsertTrailingCommas);
636     IO.mapOptional("JavaImportGroups", Style.JavaImportGroups);
637     IO.mapOptional("JavaScriptQuotes", Style.JavaScriptQuotes);
638     IO.mapOptional("JavaScriptWrapImports", Style.JavaScriptWrapImports);
639     IO.mapOptional("KeepEmptyLinesAtTheStartOfBlocks",
640                    Style.KeepEmptyLinesAtTheStartOfBlocks);
641     IO.mapOptional("MacroBlockBegin", Style.MacroBlockBegin);
642     IO.mapOptional("MacroBlockEnd", Style.MacroBlockEnd);
643     IO.mapOptional("MaxEmptyLinesToKeep", Style.MaxEmptyLinesToKeep);
644     IO.mapOptional("NamespaceIndentation", Style.NamespaceIndentation);
645     IO.mapOptional("NamespaceMacros", Style.NamespaceMacros);
646     IO.mapOptional("ObjCBinPackProtocolList", Style.ObjCBinPackProtocolList);
647     IO.mapOptional("ObjCBlockIndentWidth", Style.ObjCBlockIndentWidth);
648     IO.mapOptional("ObjCBreakBeforeNestedBlockParam",
649                    Style.ObjCBreakBeforeNestedBlockParam);
650     IO.mapOptional("ObjCSpaceAfterProperty", Style.ObjCSpaceAfterProperty);
651     IO.mapOptional("ObjCSpaceBeforeProtocolList",
652                    Style.ObjCSpaceBeforeProtocolList);
653     IO.mapOptional("PenaltyBreakAssignment", Style.PenaltyBreakAssignment);
654     IO.mapOptional("PenaltyBreakBeforeFirstCallParameter",
655                    Style.PenaltyBreakBeforeFirstCallParameter);
656     IO.mapOptional("PenaltyBreakComment", Style.PenaltyBreakComment);
657     IO.mapOptional("PenaltyBreakFirstLessLess",
658                    Style.PenaltyBreakFirstLessLess);
659     IO.mapOptional("PenaltyBreakString", Style.PenaltyBreakString);
660     IO.mapOptional("PenaltyBreakTemplateDeclaration",
661                    Style.PenaltyBreakTemplateDeclaration);
662     IO.mapOptional("PenaltyExcessCharacter", Style.PenaltyExcessCharacter);
663     IO.mapOptional("PenaltyReturnTypeOnItsOwnLine",
664                    Style.PenaltyReturnTypeOnItsOwnLine);
665     IO.mapOptional("PenaltyIndentedWhitespace",
666                    Style.PenaltyIndentedWhitespace);
667     IO.mapOptional("PointerAlignment", Style.PointerAlignment);
668     IO.mapOptional("RawStringFormats", Style.RawStringFormats);
669     IO.mapOptional("ReflowComments", Style.ReflowComments);
670     IO.mapOptional("ShortNamespaceLines", Style.ShortNamespaceLines);
671     IO.mapOptional("SortIncludes", Style.SortIncludes);
672     IO.mapOptional("SortJavaStaticImport", Style.SortJavaStaticImport);
673     IO.mapOptional("SortUsingDeclarations", Style.SortUsingDeclarations);
674     IO.mapOptional("SpaceAfterCStyleCast", Style.SpaceAfterCStyleCast);
675     IO.mapOptional("SpaceAfterLogicalNot", Style.SpaceAfterLogicalNot);
676     IO.mapOptional("SpaceAfterTemplateKeyword",
677                    Style.SpaceAfterTemplateKeyword);
678     IO.mapOptional("SpaceBeforeAssignmentOperators",
679                    Style.SpaceBeforeAssignmentOperators);
680     IO.mapOptional("SpaceBeforeCaseColon", Style.SpaceBeforeCaseColon);
681     IO.mapOptional("SpaceBeforeCpp11BracedList",
682                    Style.SpaceBeforeCpp11BracedList);
683     IO.mapOptional("SpaceBeforeCtorInitializerColon",
684                    Style.SpaceBeforeCtorInitializerColon);
685     IO.mapOptional("SpaceBeforeInheritanceColon",
686                    Style.SpaceBeforeInheritanceColon);
687     IO.mapOptional("SpaceBeforeParens", Style.SpaceBeforeParens);
688     IO.mapOptional("SpaceAroundPointerQualifiers",
689                    Style.SpaceAroundPointerQualifiers);
690     IO.mapOptional("SpaceBeforeRangeBasedForLoopColon",
691                    Style.SpaceBeforeRangeBasedForLoopColon);
692     IO.mapOptional("SpaceInEmptyBlock", Style.SpaceInEmptyBlock);
693     IO.mapOptional("SpaceInEmptyParentheses", Style.SpaceInEmptyParentheses);
694     IO.mapOptional("SpacesBeforeTrailingComments",
695                    Style.SpacesBeforeTrailingComments);
696     IO.mapOptional("SpacesInAngles", Style.SpacesInAngles);
697     IO.mapOptional("SpacesInConditionalStatement",
698                    Style.SpacesInConditionalStatement);
699     IO.mapOptional("SpacesInContainerLiterals",
700                    Style.SpacesInContainerLiterals);
701     IO.mapOptional("SpacesInCStyleCastParentheses",
702                    Style.SpacesInCStyleCastParentheses);
703     IO.mapOptional("SpacesInLineCommentPrefix",
704                    Style.SpacesInLineCommentPrefix);
705     IO.mapOptional("SpacesInParentheses", Style.SpacesInParentheses);
706     IO.mapOptional("SpacesInSquareBrackets", Style.SpacesInSquareBrackets);
707     IO.mapOptional("SpaceBeforeSquareBrackets",
708                    Style.SpaceBeforeSquareBrackets);
709     IO.mapOptional("BitFieldColonSpacing", Style.BitFieldColonSpacing);
710     IO.mapOptional("Standard", Style.Standard);
711     IO.mapOptional("StatementAttributeLikeMacros",
712                    Style.StatementAttributeLikeMacros);
713     IO.mapOptional("StatementMacros", Style.StatementMacros);
714     IO.mapOptional("TabWidth", Style.TabWidth);
715     IO.mapOptional("TypenameMacros", Style.TypenameMacros);
716     IO.mapOptional("UseCRLF", Style.UseCRLF);
717     IO.mapOptional("UseTab", Style.UseTab);
718     IO.mapOptional("WhitespaceSensitiveMacros",
719                    Style.WhitespaceSensitiveMacros);
720   }
721 };
722 
723 template <> struct MappingTraits<FormatStyle::BraceWrappingFlags> {
724   static void mapping(IO &IO, FormatStyle::BraceWrappingFlags &Wrapping) {
725     IO.mapOptional("AfterCaseLabel", Wrapping.AfterCaseLabel);
726     IO.mapOptional("AfterClass", Wrapping.AfterClass);
727     IO.mapOptional("AfterControlStatement", Wrapping.AfterControlStatement);
728     IO.mapOptional("AfterEnum", Wrapping.AfterEnum);
729     IO.mapOptional("AfterFunction", Wrapping.AfterFunction);
730     IO.mapOptional("AfterNamespace", Wrapping.AfterNamespace);
731     IO.mapOptional("AfterObjCDeclaration", Wrapping.AfterObjCDeclaration);
732     IO.mapOptional("AfterStruct", Wrapping.AfterStruct);
733     IO.mapOptional("AfterUnion", Wrapping.AfterUnion);
734     IO.mapOptional("AfterExternBlock", Wrapping.AfterExternBlock);
735     IO.mapOptional("BeforeCatch", Wrapping.BeforeCatch);
736     IO.mapOptional("BeforeElse", Wrapping.BeforeElse);
737     IO.mapOptional("BeforeLambdaBody", Wrapping.BeforeLambdaBody);
738     IO.mapOptional("BeforeWhile", Wrapping.BeforeWhile);
739     IO.mapOptional("IndentBraces", Wrapping.IndentBraces);
740     IO.mapOptional("SplitEmptyFunction", Wrapping.SplitEmptyFunction);
741     IO.mapOptional("SplitEmptyRecord", Wrapping.SplitEmptyRecord);
742     IO.mapOptional("SplitEmptyNamespace", Wrapping.SplitEmptyNamespace);
743   }
744 };
745 
746 template <> struct MappingTraits<FormatStyle::RawStringFormat> {
747   static void mapping(IO &IO, FormatStyle::RawStringFormat &Format) {
748     IO.mapOptional("Language", Format.Language);
749     IO.mapOptional("Delimiters", Format.Delimiters);
750     IO.mapOptional("EnclosingFunctions", Format.EnclosingFunctions);
751     IO.mapOptional("CanonicalDelimiter", Format.CanonicalDelimiter);
752     IO.mapOptional("BasedOnStyle", Format.BasedOnStyle);
753   }
754 };
755 
756 template <> struct MappingTraits<FormatStyle::SpacesInLineComment> {
757   static void mapping(IO &IO, FormatStyle::SpacesInLineComment &Space) {
758     // Transform the maximum to signed, to parse "-1" correctly
759     int signedMaximum = static_cast<int>(Space.Maximum);
760     IO.mapOptional("Minimum", Space.Minimum);
761     IO.mapOptional("Maximum", signedMaximum);
762     Space.Maximum = static_cast<unsigned>(signedMaximum);
763 
764     if (Space.Maximum != -1u) {
765       Space.Minimum = std::min(Space.Minimum, Space.Maximum);
766     }
767   }
768 };
769 
770 // Allows to read vector<FormatStyle> while keeping default values.
771 // IO.getContext() should contain a pointer to the FormatStyle structure, that
772 // will be used to get default values for missing keys.
773 // If the first element has no Language specified, it will be treated as the
774 // default one for the following elements.
775 template <> struct DocumentListTraits<std::vector<FormatStyle>> {
776   static size_t size(IO &IO, std::vector<FormatStyle> &Seq) {
777     return Seq.size();
778   }
779   static FormatStyle &element(IO &IO, std::vector<FormatStyle> &Seq,
780                               size_t Index) {
781     if (Index >= Seq.size()) {
782       assert(Index == Seq.size());
783       FormatStyle Template;
784       if (!Seq.empty() && Seq[0].Language == FormatStyle::LK_None) {
785         Template = Seq[0];
786       } else {
787         Template = *((const FormatStyle *)IO.getContext());
788         Template.Language = FormatStyle::LK_None;
789       }
790       Seq.resize(Index + 1, Template);
791     }
792     return Seq[Index];
793   }
794 };
795 } // namespace yaml
796 } // namespace llvm
797 
798 namespace clang {
799 namespace format {
800 
801 const std::error_category &getParseCategory() {
802   static const ParseErrorCategory C{};
803   return C;
804 }
805 std::error_code make_error_code(ParseError e) {
806   return std::error_code(static_cast<int>(e), getParseCategory());
807 }
808 
809 inline llvm::Error make_string_error(const llvm::Twine &Message) {
810   return llvm::make_error<llvm::StringError>(Message,
811                                              llvm::inconvertibleErrorCode());
812 }
813 
814 const char *ParseErrorCategory::name() const noexcept {
815   return "clang-format.parse_error";
816 }
817 
818 std::string ParseErrorCategory::message(int EV) const {
819   switch (static_cast<ParseError>(EV)) {
820   case ParseError::Success:
821     return "Success";
822   case ParseError::Error:
823     return "Invalid argument";
824   case ParseError::Unsuitable:
825     return "Unsuitable";
826   case ParseError::BinPackTrailingCommaConflict:
827     return "trailing comma insertion cannot be used with bin packing";
828   }
829   llvm_unreachable("unexpected parse error");
830 }
831 
832 static FormatStyle expandPresets(const FormatStyle &Style) {
833   if (Style.BreakBeforeBraces == FormatStyle::BS_Custom)
834     return Style;
835   FormatStyle Expanded = Style;
836   Expanded.BraceWrapping = {/*AfterCaseLabel=*/false,
837                             /*AfterClass=*/false,
838                             /*AfterControlStatement=*/FormatStyle::BWACS_Never,
839                             /*AfterEnum=*/false,
840                             /*AfterFunction=*/false,
841                             /*AfterNamespace=*/false,
842                             /*AfterObjCDeclaration=*/false,
843                             /*AfterStruct=*/false,
844                             /*AfterUnion=*/false,
845                             /*AfterExternBlock=*/false,
846                             /*BeforeCatch=*/false,
847                             /*BeforeElse=*/false,
848                             /*BeforeLambdaBody=*/false,
849                             /*BeforeWhile=*/false,
850                             /*IndentBraces=*/false,
851                             /*SplitEmptyFunction=*/true,
852                             /*SplitEmptyRecord=*/true,
853                             /*SplitEmptyNamespace=*/true};
854   switch (Style.BreakBeforeBraces) {
855   case FormatStyle::BS_Linux:
856     Expanded.BraceWrapping.AfterClass = true;
857     Expanded.BraceWrapping.AfterFunction = true;
858     Expanded.BraceWrapping.AfterNamespace = true;
859     break;
860   case FormatStyle::BS_Mozilla:
861     Expanded.BraceWrapping.AfterClass = true;
862     Expanded.BraceWrapping.AfterEnum = true;
863     Expanded.BraceWrapping.AfterFunction = true;
864     Expanded.BraceWrapping.AfterStruct = true;
865     Expanded.BraceWrapping.AfterUnion = true;
866     Expanded.BraceWrapping.AfterExternBlock = true;
867     Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
868     Expanded.BraceWrapping.SplitEmptyFunction = true;
869     Expanded.BraceWrapping.SplitEmptyRecord = false;
870     break;
871   case FormatStyle::BS_Stroustrup:
872     Expanded.BraceWrapping.AfterFunction = true;
873     Expanded.BraceWrapping.BeforeCatch = true;
874     Expanded.BraceWrapping.BeforeElse = true;
875     break;
876   case FormatStyle::BS_Allman:
877     Expanded.BraceWrapping.AfterCaseLabel = true;
878     Expanded.BraceWrapping.AfterClass = true;
879     Expanded.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Always;
880     Expanded.BraceWrapping.AfterEnum = true;
881     Expanded.BraceWrapping.AfterFunction = true;
882     Expanded.BraceWrapping.AfterNamespace = true;
883     Expanded.BraceWrapping.AfterObjCDeclaration = true;
884     Expanded.BraceWrapping.AfterStruct = true;
885     Expanded.BraceWrapping.AfterUnion = true;
886     Expanded.BraceWrapping.AfterExternBlock = true;
887     Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
888     Expanded.BraceWrapping.BeforeCatch = true;
889     Expanded.BraceWrapping.BeforeElse = true;
890     Expanded.BraceWrapping.BeforeLambdaBody = true;
891     break;
892   case FormatStyle::BS_Whitesmiths:
893     Expanded.BraceWrapping.AfterCaseLabel = true;
894     Expanded.BraceWrapping.AfterClass = true;
895     Expanded.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Always;
896     Expanded.BraceWrapping.AfterEnum = true;
897     Expanded.BraceWrapping.AfterFunction = true;
898     Expanded.BraceWrapping.AfterNamespace = true;
899     Expanded.BraceWrapping.AfterObjCDeclaration = true;
900     Expanded.BraceWrapping.AfterStruct = true;
901     Expanded.BraceWrapping.AfterExternBlock = true;
902     Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
903     Expanded.BraceWrapping.BeforeCatch = true;
904     Expanded.BraceWrapping.BeforeElse = true;
905     Expanded.BraceWrapping.BeforeLambdaBody = true;
906     break;
907   case FormatStyle::BS_GNU:
908     Expanded.BraceWrapping = {
909         /*AfterCaseLabel=*/true,
910         /*AfterClass=*/true,
911         /*AfterControlStatement=*/FormatStyle::BWACS_Always,
912         /*AfterEnum=*/true,
913         /*AfterFunction=*/true,
914         /*AfterNamespace=*/true,
915         /*AfterObjCDeclaration=*/true,
916         /*AfterStruct=*/true,
917         /*AfterUnion=*/true,
918         /*AfterExternBlock=*/true,
919         /*BeforeCatch=*/true,
920         /*BeforeElse=*/true,
921         /*BeforeLambdaBody=*/false,
922         /*BeforeWhile=*/true,
923         /*IndentBraces=*/true,
924         /*SplitEmptyFunction=*/true,
925         /*SplitEmptyRecord=*/true,
926         /*SplitEmptyNamespace=*/true};
927     Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
928     break;
929   case FormatStyle::BS_WebKit:
930     Expanded.BraceWrapping.AfterFunction = true;
931     break;
932   default:
933     break;
934   }
935   return Expanded;
936 }
937 
938 FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
939   FormatStyle LLVMStyle;
940   LLVMStyle.InheritsParentConfig = false;
941   LLVMStyle.Language = Language;
942   LLVMStyle.AccessModifierOffset = -2;
943   LLVMStyle.AlignEscapedNewlines = FormatStyle::ENAS_Right;
944   LLVMStyle.AlignAfterOpenBracket = FormatStyle::BAS_Align;
945   LLVMStyle.AlignOperands = FormatStyle::OAS_Align;
946   LLVMStyle.AlignTrailingComments = true;
947   LLVMStyle.AlignConsecutiveAssignments = FormatStyle::ACS_None;
948   LLVMStyle.AlignConsecutiveBitFields = FormatStyle::ACS_None;
949   LLVMStyle.AlignConsecutiveDeclarations = FormatStyle::ACS_None;
950   LLVMStyle.AlignConsecutiveMacros = FormatStyle::ACS_None;
951   LLVMStyle.AllowAllArgumentsOnNextLine = true;
952   LLVMStyle.AllowAllConstructorInitializersOnNextLine = true;
953   LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true;
954   LLVMStyle.AllowShortEnumsOnASingleLine = true;
955   LLVMStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
956   LLVMStyle.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Never;
957   LLVMStyle.AllowShortCaseLabelsOnASingleLine = false;
958   LLVMStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
959   LLVMStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_All;
960   LLVMStyle.AllowShortLoopsOnASingleLine = false;
961   LLVMStyle.AlwaysBreakAfterReturnType = FormatStyle::RTBS_None;
962   LLVMStyle.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_None;
963   LLVMStyle.AlwaysBreakBeforeMultilineStrings = false;
964   LLVMStyle.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_MultiLine;
965   LLVMStyle.AttributeMacros.push_back("__capability");
966   LLVMStyle.BinPackArguments = true;
967   LLVMStyle.BinPackParameters = true;
968   LLVMStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_None;
969   LLVMStyle.BreakBeforeConceptDeclarations = true;
970   LLVMStyle.BreakBeforeTernaryOperators = true;
971   LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach;
972   LLVMStyle.BraceWrapping = {/*AfterCaseLabel=*/false,
973                              /*AfterClass=*/false,
974                              /*AfterControlStatement=*/FormatStyle::BWACS_Never,
975                              /*AfterEnum=*/false,
976                              /*AfterFunction=*/false,
977                              /*AfterNamespace=*/false,
978                              /*AfterObjCDeclaration=*/false,
979                              /*AfterStruct=*/false,
980                              /*AfterUnion=*/false,
981                              /*AfterExternBlock=*/false,
982                              /*BeforeCatch=*/false,
983                              /*BeforeElse=*/false,
984                              /*BeforeLambdaBody=*/false,
985                              /*BeforeWhile=*/false,
986                              /*IndentBraces=*/false,
987                              /*SplitEmptyFunction=*/true,
988                              /*SplitEmptyRecord=*/true,
989                              /*SplitEmptyNamespace=*/true};
990   LLVMStyle.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
991   LLVMStyle.BreakAfterJavaFieldAnnotations = false;
992   LLVMStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon;
993   LLVMStyle.BreakInheritanceList = FormatStyle::BILS_BeforeColon;
994   LLVMStyle.BreakStringLiterals = true;
995   LLVMStyle.ColumnLimit = 80;
996   LLVMStyle.CommentPragmas = "^ IWYU pragma:";
997   LLVMStyle.CompactNamespaces = false;
998   LLVMStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = false;
999   LLVMStyle.ConstructorInitializerIndentWidth = 4;
1000   LLVMStyle.ContinuationIndentWidth = 4;
1001   LLVMStyle.Cpp11BracedListStyle = true;
1002   LLVMStyle.DeriveLineEnding = true;
1003   LLVMStyle.DerivePointerAlignment = false;
1004   LLVMStyle.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Never;
1005   LLVMStyle.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_LogicalBlock;
1006   LLVMStyle.ExperimentalAutoDetectBinPacking = false;
1007   LLVMStyle.FixNamespaceComments = true;
1008   LLVMStyle.ForEachMacros.push_back("foreach");
1009   LLVMStyle.ForEachMacros.push_back("Q_FOREACH");
1010   LLVMStyle.ForEachMacros.push_back("BOOST_FOREACH");
1011   LLVMStyle.IncludeStyle.IncludeCategories = {
1012       {"^\"(llvm|llvm-c|clang|clang-c)/", 2, 0, false},
1013       {"^(<|\"(gtest|gmock|isl|json)/)", 3, 0, false},
1014       {".*", 1, 0, false}};
1015   LLVMStyle.IncludeStyle.IncludeIsMainRegex = "(Test)?$";
1016   LLVMStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Preserve;
1017   LLVMStyle.IndentAccessModifiers = false;
1018   LLVMStyle.IndentCaseLabels = false;
1019   LLVMStyle.IndentCaseBlocks = false;
1020   LLVMStyle.IndentGotoLabels = true;
1021   LLVMStyle.IndentPPDirectives = FormatStyle::PPDIS_None;
1022   LLVMStyle.IndentRequires = false;
1023   LLVMStyle.IndentWrappedFunctionNames = false;
1024   LLVMStyle.IndentWidth = 2;
1025   LLVMStyle.InsertTrailingCommas = FormatStyle::TCS_None;
1026   LLVMStyle.JavaScriptQuotes = FormatStyle::JSQS_Leave;
1027   LLVMStyle.JavaScriptWrapImports = true;
1028   LLVMStyle.TabWidth = 8;
1029   LLVMStyle.MaxEmptyLinesToKeep = 1;
1030   LLVMStyle.KeepEmptyLinesAtTheStartOfBlocks = true;
1031   LLVMStyle.NamespaceIndentation = FormatStyle::NI_None;
1032   LLVMStyle.ObjCBinPackProtocolList = FormatStyle::BPS_Auto;
1033   LLVMStyle.ObjCBlockIndentWidth = 2;
1034   LLVMStyle.ObjCBreakBeforeNestedBlockParam = true;
1035   LLVMStyle.ObjCSpaceAfterProperty = false;
1036   LLVMStyle.ObjCSpaceBeforeProtocolList = true;
1037   LLVMStyle.PointerAlignment = FormatStyle::PAS_Right;
1038   LLVMStyle.ShortNamespaceLines = 1;
1039   LLVMStyle.SpacesBeforeTrailingComments = 1;
1040   LLVMStyle.Standard = FormatStyle::LS_Latest;
1041   LLVMStyle.UseCRLF = false;
1042   LLVMStyle.UseTab = FormatStyle::UT_Never;
1043   LLVMStyle.ReflowComments = true;
1044   LLVMStyle.SpacesInParentheses = false;
1045   LLVMStyle.SpacesInSquareBrackets = false;
1046   LLVMStyle.SpaceInEmptyBlock = false;
1047   LLVMStyle.SpaceInEmptyParentheses = false;
1048   LLVMStyle.SpacesInContainerLiterals = true;
1049   LLVMStyle.SpacesInCStyleCastParentheses = false;
1050   LLVMStyle.SpacesInLineCommentPrefix = {/*Minimum=*/1, /*Maximum=*/-1u};
1051   LLVMStyle.SpaceAfterCStyleCast = false;
1052   LLVMStyle.SpaceAfterLogicalNot = false;
1053   LLVMStyle.SpaceAfterTemplateKeyword = true;
1054   LLVMStyle.SpaceAroundPointerQualifiers = FormatStyle::SAPQ_Default;
1055   LLVMStyle.SpaceBeforeCaseColon = false;
1056   LLVMStyle.SpaceBeforeCtorInitializerColon = true;
1057   LLVMStyle.SpaceBeforeInheritanceColon = true;
1058   LLVMStyle.SpaceBeforeParens = FormatStyle::SBPO_ControlStatements;
1059   LLVMStyle.SpaceBeforeRangeBasedForLoopColon = true;
1060   LLVMStyle.SpaceBeforeAssignmentOperators = true;
1061   LLVMStyle.SpaceBeforeCpp11BracedList = false;
1062   LLVMStyle.SpaceBeforeSquareBrackets = false;
1063   LLVMStyle.BitFieldColonSpacing = FormatStyle::BFCS_Both;
1064   LLVMStyle.SpacesInAngles = FormatStyle::SIAS_Never;
1065   LLVMStyle.SpacesInConditionalStatement = false;
1066 
1067   LLVMStyle.PenaltyBreakAssignment = prec::Assignment;
1068   LLVMStyle.PenaltyBreakComment = 300;
1069   LLVMStyle.PenaltyBreakFirstLessLess = 120;
1070   LLVMStyle.PenaltyBreakString = 1000;
1071   LLVMStyle.PenaltyExcessCharacter = 1000000;
1072   LLVMStyle.PenaltyReturnTypeOnItsOwnLine = 60;
1073   LLVMStyle.PenaltyBreakBeforeFirstCallParameter = 19;
1074   LLVMStyle.PenaltyBreakTemplateDeclaration = prec::Relational;
1075   LLVMStyle.PenaltyIndentedWhitespace = 0;
1076 
1077   LLVMStyle.DisableFormat = false;
1078   LLVMStyle.SortIncludes = FormatStyle::SI_CaseSensitive;
1079   LLVMStyle.SortJavaStaticImport = FormatStyle::SJSIO_Before;
1080   LLVMStyle.SortUsingDeclarations = true;
1081   LLVMStyle.StatementAttributeLikeMacros.push_back("Q_EMIT");
1082   LLVMStyle.StatementMacros.push_back("Q_UNUSED");
1083   LLVMStyle.StatementMacros.push_back("QT_REQUIRE_VERSION");
1084   LLVMStyle.WhitespaceSensitiveMacros.push_back("STRINGIZE");
1085   LLVMStyle.WhitespaceSensitiveMacros.push_back("PP_STRINGIZE");
1086   LLVMStyle.WhitespaceSensitiveMacros.push_back("BOOST_PP_STRINGIZE");
1087   LLVMStyle.WhitespaceSensitiveMacros.push_back("NS_SWIFT_NAME");
1088   LLVMStyle.WhitespaceSensitiveMacros.push_back("CF_SWIFT_NAME");
1089 
1090   // Defaults that differ when not C++.
1091   if (Language == FormatStyle::LK_TableGen) {
1092     LLVMStyle.SpacesInContainerLiterals = false;
1093   }
1094 
1095   return LLVMStyle;
1096 }
1097 
1098 FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
1099   if (Language == FormatStyle::LK_TextProto) {
1100     FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_Proto);
1101     GoogleStyle.Language = FormatStyle::LK_TextProto;
1102 
1103     return GoogleStyle;
1104   }
1105 
1106   FormatStyle GoogleStyle = getLLVMStyle(Language);
1107 
1108   GoogleStyle.AccessModifierOffset = -1;
1109   GoogleStyle.AlignEscapedNewlines = FormatStyle::ENAS_Left;
1110   GoogleStyle.AllowShortIfStatementsOnASingleLine =
1111       FormatStyle::SIS_WithoutElse;
1112   GoogleStyle.AllowShortLoopsOnASingleLine = true;
1113   GoogleStyle.AlwaysBreakBeforeMultilineStrings = true;
1114   GoogleStyle.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_Yes;
1115   GoogleStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = true;
1116   GoogleStyle.DerivePointerAlignment = true;
1117   GoogleStyle.IncludeStyle.IncludeCategories = {{"^<ext/.*\\.h>", 2, 0, false},
1118                                                 {"^<.*\\.h>", 1, 0, false},
1119                                                 {"^<.*", 2, 0, false},
1120                                                 {".*", 3, 0, false}};
1121   GoogleStyle.IncludeStyle.IncludeIsMainRegex = "([-_](test|unittest))?$";
1122   GoogleStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
1123   GoogleStyle.IndentCaseLabels = true;
1124   GoogleStyle.KeepEmptyLinesAtTheStartOfBlocks = false;
1125   GoogleStyle.ObjCBinPackProtocolList = FormatStyle::BPS_Never;
1126   GoogleStyle.ObjCSpaceAfterProperty = false;
1127   GoogleStyle.ObjCSpaceBeforeProtocolList = true;
1128   GoogleStyle.PointerAlignment = FormatStyle::PAS_Left;
1129   GoogleStyle.RawStringFormats = {
1130       {
1131           FormatStyle::LK_Cpp,
1132           /*Delimiters=*/
1133           {
1134               "cc",
1135               "CC",
1136               "cpp",
1137               "Cpp",
1138               "CPP",
1139               "c++",
1140               "C++",
1141           },
1142           /*EnclosingFunctionNames=*/
1143           {},
1144           /*CanonicalDelimiter=*/"",
1145           /*BasedOnStyle=*/"google",
1146       },
1147       {
1148           FormatStyle::LK_TextProto,
1149           /*Delimiters=*/
1150           {
1151               "pb",
1152               "PB",
1153               "proto",
1154               "PROTO",
1155           },
1156           /*EnclosingFunctionNames=*/
1157           {
1158               "EqualsProto",
1159               "EquivToProto",
1160               "PARSE_PARTIAL_TEXT_PROTO",
1161               "PARSE_TEST_PROTO",
1162               "PARSE_TEXT_PROTO",
1163               "ParseTextOrDie",
1164               "ParseTextProtoOrDie",
1165               "ParseTestProto",
1166               "ParsePartialTestProto",
1167           },
1168           /*CanonicalDelimiter=*/"pb",
1169           /*BasedOnStyle=*/"google",
1170       },
1171   };
1172   GoogleStyle.SpacesBeforeTrailingComments = 2;
1173   GoogleStyle.Standard = FormatStyle::LS_Auto;
1174 
1175   GoogleStyle.PenaltyReturnTypeOnItsOwnLine = 200;
1176   GoogleStyle.PenaltyBreakBeforeFirstCallParameter = 1;
1177 
1178   if (Language == FormatStyle::LK_Java) {
1179     GoogleStyle.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign;
1180     GoogleStyle.AlignOperands = FormatStyle::OAS_DontAlign;
1181     GoogleStyle.AlignTrailingComments = false;
1182     GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
1183     GoogleStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
1184     GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
1185     GoogleStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment;
1186     GoogleStyle.ColumnLimit = 100;
1187     GoogleStyle.SpaceAfterCStyleCast = true;
1188     GoogleStyle.SpacesBeforeTrailingComments = 1;
1189   } else if (Language == FormatStyle::LK_JavaScript) {
1190     GoogleStyle.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak;
1191     GoogleStyle.AlignOperands = FormatStyle::OAS_DontAlign;
1192     GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
1193     // TODO: still under discussion whether to switch to SLS_All.
1194     GoogleStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_Empty;
1195     GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
1196     GoogleStyle.BreakBeforeTernaryOperators = false;
1197     // taze:, triple slash directives (`/// <...`), tslint:, and @see, which is
1198     // commonly followed by overlong URLs.
1199     GoogleStyle.CommentPragmas = "(taze:|^/[ \t]*<|tslint:|@see)";
1200     // TODO: enable once decided, in particular re disabling bin packing.
1201     // https://google.github.io/styleguide/jsguide.html#features-arrays-trailing-comma
1202     // GoogleStyle.InsertTrailingCommas = FormatStyle::TCS_Wrapped;
1203     GoogleStyle.MaxEmptyLinesToKeep = 3;
1204     GoogleStyle.NamespaceIndentation = FormatStyle::NI_All;
1205     GoogleStyle.SpacesInContainerLiterals = false;
1206     GoogleStyle.JavaScriptQuotes = FormatStyle::JSQS_Single;
1207     GoogleStyle.JavaScriptWrapImports = false;
1208   } else if (Language == FormatStyle::LK_Proto) {
1209     GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
1210     GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
1211     GoogleStyle.SpacesInContainerLiterals = false;
1212     GoogleStyle.Cpp11BracedListStyle = false;
1213     // This affects protocol buffer options specifications and text protos.
1214     // Text protos are currently mostly formatted inside C++ raw string literals
1215     // and often the current breaking behavior of string literals is not
1216     // beneficial there. Investigate turning this on once proper string reflow
1217     // has been implemented.
1218     GoogleStyle.BreakStringLiterals = false;
1219   } else if (Language == FormatStyle::LK_ObjC) {
1220     GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
1221     GoogleStyle.ColumnLimit = 100;
1222     // "Regroup" doesn't work well for ObjC yet (main header heuristic,
1223     // relationship between ObjC standard library headers and other heades,
1224     // #imports, etc.)
1225     GoogleStyle.IncludeStyle.IncludeBlocks =
1226         tooling::IncludeStyle::IBS_Preserve;
1227   } else if (Language == FormatStyle::LK_CSharp) {
1228     GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
1229     GoogleStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
1230     GoogleStyle.BreakStringLiterals = false;
1231     GoogleStyle.ColumnLimit = 100;
1232     GoogleStyle.NamespaceIndentation = FormatStyle::NI_All;
1233   }
1234 
1235   return GoogleStyle;
1236 }
1237 
1238 FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language) {
1239   FormatStyle ChromiumStyle = getGoogleStyle(Language);
1240 
1241   // Disable include reordering across blocks in Chromium code.
1242   // - clang-format tries to detect that foo.h is the "main" header for
1243   //   foo.cc and foo_unittest.cc via IncludeIsMainRegex. However, Chromium
1244   //   uses many other suffices (_win.cc, _mac.mm, _posix.cc, _browsertest.cc,
1245   //   _private.cc, _impl.cc etc) in different permutations
1246   //   (_win_browsertest.cc) so disable this until IncludeIsMainRegex has a
1247   //   better default for Chromium code.
1248   // - The default for .cc and .mm files is different (r357695) for Google style
1249   //   for the same reason. The plan is to unify this again once the main
1250   //   header detection works for Google's ObjC code, but this hasn't happened
1251   //   yet. Since Chromium has some ObjC code, switching Chromium is blocked
1252   //   on that.
1253   // - Finally, "If include reordering is harmful, put things in different
1254   //   blocks to prevent it" has been a recommendation for a long time that
1255   //   people are used to. We'll need a dev education push to change this to
1256   //   "If include reordering is harmful, put things in a different block and
1257   //   _prepend that with a comment_ to prevent it" before changing behavior.
1258   ChromiumStyle.IncludeStyle.IncludeBlocks =
1259       tooling::IncludeStyle::IBS_Preserve;
1260 
1261   if (Language == FormatStyle::LK_Java) {
1262     ChromiumStyle.AllowShortIfStatementsOnASingleLine =
1263         FormatStyle::SIS_WithoutElse;
1264     ChromiumStyle.BreakAfterJavaFieldAnnotations = true;
1265     ChromiumStyle.ContinuationIndentWidth = 8;
1266     ChromiumStyle.IndentWidth = 4;
1267     // See styleguide for import groups:
1268     // https://chromium.googlesource.com/chromium/src/+/master/styleguide/java/java.md#Import-Order
1269     ChromiumStyle.JavaImportGroups = {
1270         "android",
1271         "androidx",
1272         "com",
1273         "dalvik",
1274         "junit",
1275         "org",
1276         "com.google.android.apps.chrome",
1277         "org.chromium",
1278         "java",
1279         "javax",
1280     };
1281     ChromiumStyle.SortIncludes = FormatStyle::SI_CaseSensitive;
1282   } else if (Language == FormatStyle::LK_JavaScript) {
1283     ChromiumStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
1284     ChromiumStyle.AllowShortLoopsOnASingleLine = false;
1285   } else {
1286     ChromiumStyle.AllowAllParametersOfDeclarationOnNextLine = false;
1287     ChromiumStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
1288     ChromiumStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
1289     ChromiumStyle.AllowShortLoopsOnASingleLine = false;
1290     ChromiumStyle.BinPackParameters = false;
1291     ChromiumStyle.DerivePointerAlignment = false;
1292     if (Language == FormatStyle::LK_ObjC)
1293       ChromiumStyle.ColumnLimit = 80;
1294   }
1295   return ChromiumStyle;
1296 }
1297 
1298 FormatStyle getMozillaStyle() {
1299   FormatStyle MozillaStyle = getLLVMStyle();
1300   MozillaStyle.AllowAllParametersOfDeclarationOnNextLine = false;
1301   MozillaStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
1302   MozillaStyle.AlwaysBreakAfterReturnType = FormatStyle::RTBS_TopLevel;
1303   MozillaStyle.AlwaysBreakAfterDefinitionReturnType =
1304       FormatStyle::DRTBS_TopLevel;
1305   MozillaStyle.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_Yes;
1306   MozillaStyle.BinPackParameters = false;
1307   MozillaStyle.BinPackArguments = false;
1308   MozillaStyle.BreakBeforeBraces = FormatStyle::BS_Mozilla;
1309   MozillaStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma;
1310   MozillaStyle.BreakInheritanceList = FormatStyle::BILS_BeforeComma;
1311   MozillaStyle.ConstructorInitializerIndentWidth = 2;
1312   MozillaStyle.ContinuationIndentWidth = 2;
1313   MozillaStyle.Cpp11BracedListStyle = false;
1314   MozillaStyle.FixNamespaceComments = false;
1315   MozillaStyle.IndentCaseLabels = true;
1316   MozillaStyle.ObjCSpaceAfterProperty = true;
1317   MozillaStyle.ObjCSpaceBeforeProtocolList = false;
1318   MozillaStyle.PenaltyReturnTypeOnItsOwnLine = 200;
1319   MozillaStyle.PointerAlignment = FormatStyle::PAS_Left;
1320   MozillaStyle.SpaceAfterTemplateKeyword = false;
1321   return MozillaStyle;
1322 }
1323 
1324 FormatStyle getWebKitStyle() {
1325   FormatStyle Style = getLLVMStyle();
1326   Style.AccessModifierOffset = -4;
1327   Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign;
1328   Style.AlignOperands = FormatStyle::OAS_DontAlign;
1329   Style.AlignTrailingComments = false;
1330   Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Empty;
1331   Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All;
1332   Style.BreakBeforeBraces = FormatStyle::BS_WebKit;
1333   Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma;
1334   Style.Cpp11BracedListStyle = false;
1335   Style.ColumnLimit = 0;
1336   Style.FixNamespaceComments = false;
1337   Style.IndentWidth = 4;
1338   Style.NamespaceIndentation = FormatStyle::NI_Inner;
1339   Style.ObjCBlockIndentWidth = 4;
1340   Style.ObjCSpaceAfterProperty = true;
1341   Style.PointerAlignment = FormatStyle::PAS_Left;
1342   Style.SpaceBeforeCpp11BracedList = true;
1343   Style.SpaceInEmptyBlock = true;
1344   return Style;
1345 }
1346 
1347 FormatStyle getGNUStyle() {
1348   FormatStyle Style = getLLVMStyle();
1349   Style.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_All;
1350   Style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_AllDefinitions;
1351   Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All;
1352   Style.BreakBeforeBraces = FormatStyle::BS_GNU;
1353   Style.BreakBeforeTernaryOperators = true;
1354   Style.Cpp11BracedListStyle = false;
1355   Style.ColumnLimit = 79;
1356   Style.FixNamespaceComments = false;
1357   Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
1358   Style.Standard = FormatStyle::LS_Cpp03;
1359   return Style;
1360 }
1361 
1362 FormatStyle getMicrosoftStyle(FormatStyle::LanguageKind Language) {
1363   FormatStyle Style = getLLVMStyle(Language);
1364   Style.ColumnLimit = 120;
1365   Style.TabWidth = 4;
1366   Style.IndentWidth = 4;
1367   Style.UseTab = FormatStyle::UT_Never;
1368   Style.BreakBeforeBraces = FormatStyle::BS_Custom;
1369   Style.BraceWrapping.AfterClass = true;
1370   Style.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Always;
1371   Style.BraceWrapping.AfterEnum = true;
1372   Style.BraceWrapping.AfterFunction = true;
1373   Style.BraceWrapping.AfterNamespace = true;
1374   Style.BraceWrapping.AfterObjCDeclaration = true;
1375   Style.BraceWrapping.AfterStruct = true;
1376   Style.BraceWrapping.AfterExternBlock = true;
1377   Style.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
1378   Style.BraceWrapping.BeforeCatch = true;
1379   Style.BraceWrapping.BeforeElse = true;
1380   Style.BraceWrapping.BeforeWhile = false;
1381   Style.PenaltyReturnTypeOnItsOwnLine = 1000;
1382   Style.AllowShortEnumsOnASingleLine = false;
1383   Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
1384   Style.AllowShortCaseLabelsOnASingleLine = false;
1385   Style.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
1386   Style.AllowShortLoopsOnASingleLine = false;
1387   Style.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_None;
1388   Style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_None;
1389   return Style;
1390 }
1391 
1392 FormatStyle getNoStyle() {
1393   FormatStyle NoStyle = getLLVMStyle();
1394   NoStyle.DisableFormat = true;
1395   NoStyle.SortIncludes = FormatStyle::SI_Never;
1396   NoStyle.SortUsingDeclarations = false;
1397   return NoStyle;
1398 }
1399 
1400 bool getPredefinedStyle(StringRef Name, FormatStyle::LanguageKind Language,
1401                         FormatStyle *Style) {
1402   if (Name.equals_lower("llvm")) {
1403     *Style = getLLVMStyle(Language);
1404   } else if (Name.equals_lower("chromium")) {
1405     *Style = getChromiumStyle(Language);
1406   } else if (Name.equals_lower("mozilla")) {
1407     *Style = getMozillaStyle();
1408   } else if (Name.equals_lower("google")) {
1409     *Style = getGoogleStyle(Language);
1410   } else if (Name.equals_lower("webkit")) {
1411     *Style = getWebKitStyle();
1412   } else if (Name.equals_lower("gnu")) {
1413     *Style = getGNUStyle();
1414   } else if (Name.equals_lower("microsoft")) {
1415     *Style = getMicrosoftStyle(Language);
1416   } else if (Name.equals_lower("none")) {
1417     *Style = getNoStyle();
1418   } else if (Name.equals_lower("inheritparentconfig")) {
1419     Style->InheritsParentConfig = true;
1420   } else {
1421     return false;
1422   }
1423 
1424   Style->Language = Language;
1425   return true;
1426 }
1427 
1428 std::error_code parseConfiguration(llvm::MemoryBufferRef Config,
1429                                    FormatStyle *Style, bool AllowUnknownOptions,
1430                                    llvm::SourceMgr::DiagHandlerTy DiagHandler,
1431                                    void *DiagHandlerCtxt) {
1432   assert(Style);
1433   FormatStyle::LanguageKind Language = Style->Language;
1434   assert(Language != FormatStyle::LK_None);
1435   if (Config.getBuffer().trim().empty())
1436     return make_error_code(ParseError::Error);
1437   Style->StyleSet.Clear();
1438   std::vector<FormatStyle> Styles;
1439   llvm::yaml::Input Input(Config, /*Ctxt=*/nullptr, DiagHandler,
1440                           DiagHandlerCtxt);
1441   // DocumentListTraits<vector<FormatStyle>> uses the context to get default
1442   // values for the fields, keys for which are missing from the configuration.
1443   // Mapping also uses the context to get the language to find the correct
1444   // base style.
1445   Input.setContext(Style);
1446   Input.setAllowUnknownKeys(AllowUnknownOptions);
1447   Input >> Styles;
1448   if (Input.error())
1449     return Input.error();
1450 
1451   for (unsigned i = 0; i < Styles.size(); ++i) {
1452     // Ensures that only the first configuration can skip the Language option.
1453     if (Styles[i].Language == FormatStyle::LK_None && i != 0)
1454       return make_error_code(ParseError::Error);
1455     // Ensure that each language is configured at most once.
1456     for (unsigned j = 0; j < i; ++j) {
1457       if (Styles[i].Language == Styles[j].Language) {
1458         LLVM_DEBUG(llvm::dbgs()
1459                    << "Duplicate languages in the config file on positions "
1460                    << j << " and " << i << "\n");
1461         return make_error_code(ParseError::Error);
1462       }
1463     }
1464   }
1465   // Look for a suitable configuration starting from the end, so we can
1466   // find the configuration for the specific language first, and the default
1467   // configuration (which can only be at slot 0) after it.
1468   FormatStyle::FormatStyleSet StyleSet;
1469   bool LanguageFound = false;
1470   for (int i = Styles.size() - 1; i >= 0; --i) {
1471     if (Styles[i].Language != FormatStyle::LK_None)
1472       StyleSet.Add(Styles[i]);
1473     if (Styles[i].Language == Language)
1474       LanguageFound = true;
1475   }
1476   if (!LanguageFound) {
1477     if (Styles.empty() || Styles[0].Language != FormatStyle::LK_None)
1478       return make_error_code(ParseError::Unsuitable);
1479     FormatStyle DefaultStyle = Styles[0];
1480     DefaultStyle.Language = Language;
1481     StyleSet.Add(std::move(DefaultStyle));
1482   }
1483   *Style = *StyleSet.Get(Language);
1484   if (Style->InsertTrailingCommas != FormatStyle::TCS_None &&
1485       Style->BinPackArguments) {
1486     // See comment on FormatStyle::TSC_Wrapped.
1487     return make_error_code(ParseError::BinPackTrailingCommaConflict);
1488   }
1489   return make_error_code(ParseError::Success);
1490 }
1491 
1492 std::string configurationAsText(const FormatStyle &Style) {
1493   std::string Text;
1494   llvm::raw_string_ostream Stream(Text);
1495   llvm::yaml::Output Output(Stream);
1496   // We use the same mapping method for input and output, so we need a non-const
1497   // reference here.
1498   FormatStyle NonConstStyle = expandPresets(Style);
1499   Output << NonConstStyle;
1500   return Stream.str();
1501 }
1502 
1503 llvm::Optional<FormatStyle>
1504 FormatStyle::FormatStyleSet::Get(FormatStyle::LanguageKind Language) const {
1505   if (!Styles)
1506     return None;
1507   auto It = Styles->find(Language);
1508   if (It == Styles->end())
1509     return None;
1510   FormatStyle Style = It->second;
1511   Style.StyleSet = *this;
1512   return Style;
1513 }
1514 
1515 void FormatStyle::FormatStyleSet::Add(FormatStyle Style) {
1516   assert(Style.Language != LK_None &&
1517          "Cannot add a style for LK_None to a StyleSet");
1518   assert(
1519       !Style.StyleSet.Styles &&
1520       "Cannot add a style associated with an existing StyleSet to a StyleSet");
1521   if (!Styles)
1522     Styles = std::make_shared<MapType>();
1523   (*Styles)[Style.Language] = std::move(Style);
1524 }
1525 
1526 void FormatStyle::FormatStyleSet::Clear() { Styles.reset(); }
1527 
1528 llvm::Optional<FormatStyle>
1529 FormatStyle::GetLanguageStyle(FormatStyle::LanguageKind Language) const {
1530   return StyleSet.Get(Language);
1531 }
1532 
1533 namespace {
1534 
1535 class JavaScriptRequoter : public TokenAnalyzer {
1536 public:
1537   JavaScriptRequoter(const Environment &Env, const FormatStyle &Style)
1538       : TokenAnalyzer(Env, Style) {}
1539 
1540   std::pair<tooling::Replacements, unsigned>
1541   analyze(TokenAnnotator &Annotator,
1542           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
1543           FormatTokenLexer &Tokens) override {
1544     AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
1545     tooling::Replacements Result;
1546     requoteJSStringLiteral(AnnotatedLines, Result);
1547     return {Result, 0};
1548   }
1549 
1550 private:
1551   // Replaces double/single-quoted string literal as appropriate, re-escaping
1552   // the contents in the process.
1553   void requoteJSStringLiteral(SmallVectorImpl<AnnotatedLine *> &Lines,
1554                               tooling::Replacements &Result) {
1555     for (AnnotatedLine *Line : Lines) {
1556       requoteJSStringLiteral(Line->Children, Result);
1557       if (!Line->Affected)
1558         continue;
1559       for (FormatToken *FormatTok = Line->First; FormatTok;
1560            FormatTok = FormatTok->Next) {
1561         StringRef Input = FormatTok->TokenText;
1562         if (FormatTok->Finalized || !FormatTok->isStringLiteral() ||
1563             // NB: testing for not starting with a double quote to avoid
1564             // breaking `template strings`.
1565             (Style.JavaScriptQuotes == FormatStyle::JSQS_Single &&
1566              !Input.startswith("\"")) ||
1567             (Style.JavaScriptQuotes == FormatStyle::JSQS_Double &&
1568              !Input.startswith("\'")))
1569           continue;
1570 
1571         // Change start and end quote.
1572         bool IsSingle = Style.JavaScriptQuotes == FormatStyle::JSQS_Single;
1573         SourceLocation Start = FormatTok->Tok.getLocation();
1574         auto Replace = [&](SourceLocation Start, unsigned Length,
1575                            StringRef ReplacementText) {
1576           auto Err = Result.add(tooling::Replacement(
1577               Env.getSourceManager(), Start, Length, ReplacementText));
1578           // FIXME: handle error. For now, print error message and skip the
1579           // replacement for release version.
1580           if (Err) {
1581             llvm::errs() << llvm::toString(std::move(Err)) << "\n";
1582             assert(false);
1583           }
1584         };
1585         Replace(Start, 1, IsSingle ? "'" : "\"");
1586         Replace(FormatTok->Tok.getEndLoc().getLocWithOffset(-1), 1,
1587                 IsSingle ? "'" : "\"");
1588 
1589         // Escape internal quotes.
1590         bool Escaped = false;
1591         for (size_t i = 1; i < Input.size() - 1; i++) {
1592           switch (Input[i]) {
1593           case '\\':
1594             if (!Escaped && i + 1 < Input.size() &&
1595                 ((IsSingle && Input[i + 1] == '"') ||
1596                  (!IsSingle && Input[i + 1] == '\''))) {
1597               // Remove this \, it's escaping a " or ' that no longer needs
1598               // escaping
1599               Replace(Start.getLocWithOffset(i), 1, "");
1600               continue;
1601             }
1602             Escaped = !Escaped;
1603             break;
1604           case '\"':
1605           case '\'':
1606             if (!Escaped && IsSingle == (Input[i] == '\'')) {
1607               // Escape the quote.
1608               Replace(Start.getLocWithOffset(i), 0, "\\");
1609             }
1610             Escaped = false;
1611             break;
1612           default:
1613             Escaped = false;
1614             break;
1615           }
1616         }
1617       }
1618     }
1619   }
1620 };
1621 
1622 class Formatter : public TokenAnalyzer {
1623 public:
1624   Formatter(const Environment &Env, const FormatStyle &Style,
1625             FormattingAttemptStatus *Status)
1626       : TokenAnalyzer(Env, Style), Status(Status) {}
1627 
1628   std::pair<tooling::Replacements, unsigned>
1629   analyze(TokenAnnotator &Annotator,
1630           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
1631           FormatTokenLexer &Tokens) override {
1632     tooling::Replacements Result;
1633     deriveLocalStyle(AnnotatedLines);
1634     AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
1635     for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
1636       Annotator.calculateFormattingInformation(*AnnotatedLines[i]);
1637     }
1638     Annotator.setCommentLineLevels(AnnotatedLines);
1639 
1640     WhitespaceManager Whitespaces(
1641         Env.getSourceManager(), Style,
1642         Style.DeriveLineEnding
1643             ? inputUsesCRLF(
1644                   Env.getSourceManager().getBufferData(Env.getFileID()),
1645                   Style.UseCRLF)
1646             : Style.UseCRLF);
1647     ContinuationIndenter Indenter(Style, Tokens.getKeywords(),
1648                                   Env.getSourceManager(), Whitespaces, Encoding,
1649                                   BinPackInconclusiveFunctions);
1650     unsigned Penalty =
1651         UnwrappedLineFormatter(&Indenter, &Whitespaces, Style,
1652                                Tokens.getKeywords(), Env.getSourceManager(),
1653                                Status)
1654             .format(AnnotatedLines, /*DryRun=*/false,
1655                     /*AdditionalIndent=*/0,
1656                     /*FixBadIndentation=*/false,
1657                     /*FirstStartColumn=*/Env.getFirstStartColumn(),
1658                     /*NextStartColumn=*/Env.getNextStartColumn(),
1659                     /*LastStartColumn=*/Env.getLastStartColumn());
1660     for (const auto &R : Whitespaces.generateReplacements())
1661       if (Result.add(R))
1662         return std::make_pair(Result, 0);
1663     return std::make_pair(Result, Penalty);
1664   }
1665 
1666 private:
1667   static bool inputUsesCRLF(StringRef Text, bool DefaultToCRLF) {
1668     size_t LF = Text.count('\n');
1669     size_t CR = Text.count('\r') * 2;
1670     return LF == CR ? DefaultToCRLF : CR > LF;
1671   }
1672 
1673   bool
1674   hasCpp03IncompatibleFormat(const SmallVectorImpl<AnnotatedLine *> &Lines) {
1675     for (const AnnotatedLine *Line : Lines) {
1676       if (hasCpp03IncompatibleFormat(Line->Children))
1677         return true;
1678       for (FormatToken *Tok = Line->First->Next; Tok; Tok = Tok->Next) {
1679         if (Tok->WhitespaceRange.getBegin() == Tok->WhitespaceRange.getEnd()) {
1680           if (Tok->is(tok::coloncolon) && Tok->Previous->is(TT_TemplateOpener))
1681             return true;
1682           if (Tok->is(TT_TemplateCloser) &&
1683               Tok->Previous->is(TT_TemplateCloser))
1684             return true;
1685         }
1686       }
1687     }
1688     return false;
1689   }
1690 
1691   int countVariableAlignments(const SmallVectorImpl<AnnotatedLine *> &Lines) {
1692     int AlignmentDiff = 0;
1693     for (const AnnotatedLine *Line : Lines) {
1694       AlignmentDiff += countVariableAlignments(Line->Children);
1695       for (FormatToken *Tok = Line->First; Tok && Tok->Next; Tok = Tok->Next) {
1696         if (!Tok->is(TT_PointerOrReference))
1697           continue;
1698         bool SpaceBefore =
1699             Tok->WhitespaceRange.getBegin() != Tok->WhitespaceRange.getEnd();
1700         bool SpaceAfter = Tok->Next->WhitespaceRange.getBegin() !=
1701                           Tok->Next->WhitespaceRange.getEnd();
1702         if (SpaceBefore && !SpaceAfter)
1703           ++AlignmentDiff;
1704         if (!SpaceBefore && SpaceAfter)
1705           --AlignmentDiff;
1706       }
1707     }
1708     return AlignmentDiff;
1709   }
1710 
1711   void
1712   deriveLocalStyle(const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
1713     bool HasBinPackedFunction = false;
1714     bool HasOnePerLineFunction = false;
1715     for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
1716       if (!AnnotatedLines[i]->First->Next)
1717         continue;
1718       FormatToken *Tok = AnnotatedLines[i]->First->Next;
1719       while (Tok->Next) {
1720         if (Tok->is(PPK_BinPacked))
1721           HasBinPackedFunction = true;
1722         if (Tok->is(PPK_OnePerLine))
1723           HasOnePerLineFunction = true;
1724 
1725         Tok = Tok->Next;
1726       }
1727     }
1728     if (Style.DerivePointerAlignment)
1729       Style.PointerAlignment = countVariableAlignments(AnnotatedLines) <= 0
1730                                    ? FormatStyle::PAS_Left
1731                                    : FormatStyle::PAS_Right;
1732     if (Style.Standard == FormatStyle::LS_Auto)
1733       Style.Standard = hasCpp03IncompatibleFormat(AnnotatedLines)
1734                            ? FormatStyle::LS_Latest
1735                            : FormatStyle::LS_Cpp03;
1736     BinPackInconclusiveFunctions =
1737         HasBinPackedFunction || !HasOnePerLineFunction;
1738   }
1739 
1740   bool BinPackInconclusiveFunctions;
1741   FormattingAttemptStatus *Status;
1742 };
1743 
1744 /// TrailingCommaInserter inserts trailing commas into container literals.
1745 /// E.g.:
1746 ///     const x = [
1747 ///       1,
1748 ///     ];
1749 /// TrailingCommaInserter runs after formatting. To avoid causing a required
1750 /// reformatting (and thus reflow), it never inserts a comma that'd exceed the
1751 /// ColumnLimit.
1752 ///
1753 /// Because trailing commas disable binpacking of arrays, TrailingCommaInserter
1754 /// is conceptually incompatible with bin packing.
1755 class TrailingCommaInserter : public TokenAnalyzer {
1756 public:
1757   TrailingCommaInserter(const Environment &Env, const FormatStyle &Style)
1758       : TokenAnalyzer(Env, Style) {}
1759 
1760   std::pair<tooling::Replacements, unsigned>
1761   analyze(TokenAnnotator &Annotator,
1762           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
1763           FormatTokenLexer &Tokens) override {
1764     AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
1765     tooling::Replacements Result;
1766     insertTrailingCommas(AnnotatedLines, Result);
1767     return {Result, 0};
1768   }
1769 
1770 private:
1771   /// Inserts trailing commas in [] and {} initializers if they wrap over
1772   /// multiple lines.
1773   void insertTrailingCommas(SmallVectorImpl<AnnotatedLine *> &Lines,
1774                             tooling::Replacements &Result) {
1775     for (AnnotatedLine *Line : Lines) {
1776       insertTrailingCommas(Line->Children, Result);
1777       if (!Line->Affected)
1778         continue;
1779       for (FormatToken *FormatTok = Line->First; FormatTok;
1780            FormatTok = FormatTok->Next) {
1781         if (FormatTok->NewlinesBefore == 0)
1782           continue;
1783         FormatToken *Matching = FormatTok->MatchingParen;
1784         if (!Matching || !FormatTok->getPreviousNonComment())
1785           continue;
1786         if (!(FormatTok->is(tok::r_square) &&
1787               Matching->is(TT_ArrayInitializerLSquare)) &&
1788             !(FormatTok->is(tok::r_brace) && Matching->is(TT_DictLiteral)))
1789           continue;
1790         FormatToken *Prev = FormatTok->getPreviousNonComment();
1791         if (Prev->is(tok::comma) || Prev->is(tok::semi))
1792           continue;
1793         // getEndLoc is not reliably set during re-lexing, use text length
1794         // instead.
1795         SourceLocation Start =
1796             Prev->Tok.getLocation().getLocWithOffset(Prev->TokenText.size());
1797         // If inserting a comma would push the code over the column limit, skip
1798         // this location - it'd introduce an unstable formatting due to the
1799         // required reflow.
1800         unsigned ColumnNumber =
1801             Env.getSourceManager().getSpellingColumnNumber(Start);
1802         if (ColumnNumber > Style.ColumnLimit)
1803           continue;
1804         // Comma insertions cannot conflict with each other, and this pass has a
1805         // clean set of Replacements, so the operation below cannot fail.
1806         cantFail(Result.add(
1807             tooling::Replacement(Env.getSourceManager(), Start, 0, ",")));
1808       }
1809     }
1810   }
1811 };
1812 
1813 // This class clean up the erroneous/redundant code around the given ranges in
1814 // file.
1815 class Cleaner : public TokenAnalyzer {
1816 public:
1817   Cleaner(const Environment &Env, const FormatStyle &Style)
1818       : TokenAnalyzer(Env, Style),
1819         DeletedTokens(FormatTokenLess(Env.getSourceManager())) {}
1820 
1821   // FIXME: eliminate unused parameters.
1822   std::pair<tooling::Replacements, unsigned>
1823   analyze(TokenAnnotator &Annotator,
1824           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
1825           FormatTokenLexer &Tokens) override {
1826     // FIXME: in the current implementation the granularity of affected range
1827     // is an annotated line. However, this is not sufficient. Furthermore,
1828     // redundant code introduced by replacements does not necessarily
1829     // intercept with ranges of replacements that result in the redundancy.
1830     // To determine if some redundant code is actually introduced by
1831     // replacements(e.g. deletions), we need to come up with a more
1832     // sophisticated way of computing affected ranges.
1833     AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
1834 
1835     checkEmptyNamespace(AnnotatedLines);
1836 
1837     for (auto *Line : AnnotatedLines)
1838       cleanupLine(Line);
1839 
1840     return {generateFixes(), 0};
1841   }
1842 
1843 private:
1844   void cleanupLine(AnnotatedLine *Line) {
1845     for (auto *Child : Line->Children) {
1846       cleanupLine(Child);
1847     }
1848 
1849     if (Line->Affected) {
1850       cleanupRight(Line->First, tok::comma, tok::comma);
1851       cleanupRight(Line->First, TT_CtorInitializerColon, tok::comma);
1852       cleanupRight(Line->First, tok::l_paren, tok::comma);
1853       cleanupLeft(Line->First, tok::comma, tok::r_paren);
1854       cleanupLeft(Line->First, TT_CtorInitializerComma, tok::l_brace);
1855       cleanupLeft(Line->First, TT_CtorInitializerColon, tok::l_brace);
1856       cleanupLeft(Line->First, TT_CtorInitializerColon, tok::equal);
1857     }
1858   }
1859 
1860   bool containsOnlyComments(const AnnotatedLine &Line) {
1861     for (FormatToken *Tok = Line.First; Tok != nullptr; Tok = Tok->Next) {
1862       if (Tok->isNot(tok::comment))
1863         return false;
1864     }
1865     return true;
1866   }
1867 
1868   // Iterate through all lines and remove any empty (nested) namespaces.
1869   void checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
1870     std::set<unsigned> DeletedLines;
1871     for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
1872       auto &Line = *AnnotatedLines[i];
1873       if (Line.startsWithNamespace()) {
1874         checkEmptyNamespace(AnnotatedLines, i, i, DeletedLines);
1875       }
1876     }
1877 
1878     for (auto Line : DeletedLines) {
1879       FormatToken *Tok = AnnotatedLines[Line]->First;
1880       while (Tok) {
1881         deleteToken(Tok);
1882         Tok = Tok->Next;
1883       }
1884     }
1885   }
1886 
1887   // The function checks if the namespace, which starts from \p CurrentLine, and
1888   // its nested namespaces are empty and delete them if they are empty. It also
1889   // sets \p NewLine to the last line checked.
1890   // Returns true if the current namespace is empty.
1891   bool checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
1892                            unsigned CurrentLine, unsigned &NewLine,
1893                            std::set<unsigned> &DeletedLines) {
1894     unsigned InitLine = CurrentLine, End = AnnotatedLines.size();
1895     if (Style.BraceWrapping.AfterNamespace) {
1896       // If the left brace is in a new line, we should consume it first so that
1897       // it does not make the namespace non-empty.
1898       // FIXME: error handling if there is no left brace.
1899       if (!AnnotatedLines[++CurrentLine]->startsWith(tok::l_brace)) {
1900         NewLine = CurrentLine;
1901         return false;
1902       }
1903     } else if (!AnnotatedLines[CurrentLine]->endsWith(tok::l_brace)) {
1904       return false;
1905     }
1906     while (++CurrentLine < End) {
1907       if (AnnotatedLines[CurrentLine]->startsWith(tok::r_brace))
1908         break;
1909 
1910       if (AnnotatedLines[CurrentLine]->startsWithNamespace()) {
1911         if (!checkEmptyNamespace(AnnotatedLines, CurrentLine, NewLine,
1912                                  DeletedLines))
1913           return false;
1914         CurrentLine = NewLine;
1915         continue;
1916       }
1917 
1918       if (containsOnlyComments(*AnnotatedLines[CurrentLine]))
1919         continue;
1920 
1921       // If there is anything other than comments or nested namespaces in the
1922       // current namespace, the namespace cannot be empty.
1923       NewLine = CurrentLine;
1924       return false;
1925     }
1926 
1927     NewLine = CurrentLine;
1928     if (CurrentLine >= End)
1929       return false;
1930 
1931     // Check if the empty namespace is actually affected by changed ranges.
1932     if (!AffectedRangeMgr.affectsCharSourceRange(CharSourceRange::getCharRange(
1933             AnnotatedLines[InitLine]->First->Tok.getLocation(),
1934             AnnotatedLines[CurrentLine]->Last->Tok.getEndLoc())))
1935       return false;
1936 
1937     for (unsigned i = InitLine; i <= CurrentLine; ++i) {
1938       DeletedLines.insert(i);
1939     }
1940 
1941     return true;
1942   }
1943 
1944   // Checks pairs {start, start->next},..., {end->previous, end} and deletes one
1945   // of the token in the pair if the left token has \p LK token kind and the
1946   // right token has \p RK token kind. If \p DeleteLeft is true, the left token
1947   // is deleted on match; otherwise, the right token is deleted.
1948   template <typename LeftKind, typename RightKind>
1949   void cleanupPair(FormatToken *Start, LeftKind LK, RightKind RK,
1950                    bool DeleteLeft) {
1951     auto NextNotDeleted = [this](const FormatToken &Tok) -> FormatToken * {
1952       for (auto *Res = Tok.Next; Res; Res = Res->Next)
1953         if (!Res->is(tok::comment) &&
1954             DeletedTokens.find(Res) == DeletedTokens.end())
1955           return Res;
1956       return nullptr;
1957     };
1958     for (auto *Left = Start; Left;) {
1959       auto *Right = NextNotDeleted(*Left);
1960       if (!Right)
1961         break;
1962       if (Left->is(LK) && Right->is(RK)) {
1963         deleteToken(DeleteLeft ? Left : Right);
1964         for (auto *Tok = Left->Next; Tok && Tok != Right; Tok = Tok->Next)
1965           deleteToken(Tok);
1966         // If the right token is deleted, we should keep the left token
1967         // unchanged and pair it with the new right token.
1968         if (!DeleteLeft)
1969           continue;
1970       }
1971       Left = Right;
1972     }
1973   }
1974 
1975   template <typename LeftKind, typename RightKind>
1976   void cleanupLeft(FormatToken *Start, LeftKind LK, RightKind RK) {
1977     cleanupPair(Start, LK, RK, /*DeleteLeft=*/true);
1978   }
1979 
1980   template <typename LeftKind, typename RightKind>
1981   void cleanupRight(FormatToken *Start, LeftKind LK, RightKind RK) {
1982     cleanupPair(Start, LK, RK, /*DeleteLeft=*/false);
1983   }
1984 
1985   // Delete the given token.
1986   inline void deleteToken(FormatToken *Tok) {
1987     if (Tok)
1988       DeletedTokens.insert(Tok);
1989   }
1990 
1991   tooling::Replacements generateFixes() {
1992     tooling::Replacements Fixes;
1993     std::vector<FormatToken *> Tokens;
1994     std::copy(DeletedTokens.begin(), DeletedTokens.end(),
1995               std::back_inserter(Tokens));
1996 
1997     // Merge multiple continuous token deletions into one big deletion so that
1998     // the number of replacements can be reduced. This makes computing affected
1999     // ranges more efficient when we run reformat on the changed code.
2000     unsigned Idx = 0;
2001     while (Idx < Tokens.size()) {
2002       unsigned St = Idx, End = Idx;
2003       while ((End + 1) < Tokens.size() &&
2004              Tokens[End]->Next == Tokens[End + 1]) {
2005         End++;
2006       }
2007       auto SR = CharSourceRange::getCharRange(Tokens[St]->Tok.getLocation(),
2008                                               Tokens[End]->Tok.getEndLoc());
2009       auto Err =
2010           Fixes.add(tooling::Replacement(Env.getSourceManager(), SR, ""));
2011       // FIXME: better error handling. for now just print error message and skip
2012       // for the release version.
2013       if (Err) {
2014         llvm::errs() << llvm::toString(std::move(Err)) << "\n";
2015         assert(false && "Fixes must not conflict!");
2016       }
2017       Idx = End + 1;
2018     }
2019 
2020     return Fixes;
2021   }
2022 
2023   // Class for less-than inequality comparason for the set `RedundantTokens`.
2024   // We store tokens in the order they appear in the translation unit so that
2025   // we do not need to sort them in `generateFixes()`.
2026   struct FormatTokenLess {
2027     FormatTokenLess(const SourceManager &SM) : SM(SM) {}
2028 
2029     bool operator()(const FormatToken *LHS, const FormatToken *RHS) const {
2030       return SM.isBeforeInTranslationUnit(LHS->Tok.getLocation(),
2031                                           RHS->Tok.getLocation());
2032     }
2033     const SourceManager &SM;
2034   };
2035 
2036   // Tokens to be deleted.
2037   std::set<FormatToken *, FormatTokenLess> DeletedTokens;
2038 };
2039 
2040 class ObjCHeaderStyleGuesser : public TokenAnalyzer {
2041 public:
2042   ObjCHeaderStyleGuesser(const Environment &Env, const FormatStyle &Style)
2043       : TokenAnalyzer(Env, Style), IsObjC(false) {}
2044 
2045   std::pair<tooling::Replacements, unsigned>
2046   analyze(TokenAnnotator &Annotator,
2047           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2048           FormatTokenLexer &Tokens) override {
2049     assert(Style.Language == FormatStyle::LK_Cpp);
2050     IsObjC = guessIsObjC(Env.getSourceManager(), AnnotatedLines,
2051                          Tokens.getKeywords());
2052     tooling::Replacements Result;
2053     return {Result, 0};
2054   }
2055 
2056   bool isObjC() { return IsObjC; }
2057 
2058 private:
2059   static bool
2060   guessIsObjC(const SourceManager &SourceManager,
2061               const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
2062               const AdditionalKeywords &Keywords) {
2063     // Keep this array sorted, since we are binary searching over it.
2064     static constexpr llvm::StringLiteral FoundationIdentifiers[] = {
2065         "CGFloat",
2066         "CGPoint",
2067         "CGPointMake",
2068         "CGPointZero",
2069         "CGRect",
2070         "CGRectEdge",
2071         "CGRectInfinite",
2072         "CGRectMake",
2073         "CGRectNull",
2074         "CGRectZero",
2075         "CGSize",
2076         "CGSizeMake",
2077         "CGVector",
2078         "CGVectorMake",
2079         "NSAffineTransform",
2080         "NSArray",
2081         "NSAttributedString",
2082         "NSBlockOperation",
2083         "NSBundle",
2084         "NSCache",
2085         "NSCalendar",
2086         "NSCharacterSet",
2087         "NSCountedSet",
2088         "NSData",
2089         "NSDataDetector",
2090         "NSDecimal",
2091         "NSDecimalNumber",
2092         "NSDictionary",
2093         "NSEdgeInsets",
2094         "NSHashTable",
2095         "NSIndexPath",
2096         "NSIndexSet",
2097         "NSInteger",
2098         "NSInvocationOperation",
2099         "NSLocale",
2100         "NSMapTable",
2101         "NSMutableArray",
2102         "NSMutableAttributedString",
2103         "NSMutableCharacterSet",
2104         "NSMutableData",
2105         "NSMutableDictionary",
2106         "NSMutableIndexSet",
2107         "NSMutableOrderedSet",
2108         "NSMutableSet",
2109         "NSMutableString",
2110         "NSNumber",
2111         "NSNumberFormatter",
2112         "NSObject",
2113         "NSOperation",
2114         "NSOperationQueue",
2115         "NSOperationQueuePriority",
2116         "NSOrderedSet",
2117         "NSPoint",
2118         "NSPointerArray",
2119         "NSQualityOfService",
2120         "NSRange",
2121         "NSRect",
2122         "NSRegularExpression",
2123         "NSSet",
2124         "NSSize",
2125         "NSString",
2126         "NSTimeZone",
2127         "NSUInteger",
2128         "NSURL",
2129         "NSURLComponents",
2130         "NSURLQueryItem",
2131         "NSUUID",
2132         "NSValue",
2133         "UIImage",
2134         "UIView",
2135     };
2136 
2137     for (auto Line : AnnotatedLines) {
2138       if (Line->First && (Line->First->TokenText.startswith("#") ||
2139                           Line->First->TokenText == "__pragma" ||
2140                           Line->First->TokenText == "_Pragma"))
2141         continue;
2142       for (const FormatToken *FormatTok = Line->First; FormatTok;
2143            FormatTok = FormatTok->Next) {
2144         if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) &&
2145              (FormatTok->Tok.getObjCKeywordID() != tok::objc_not_keyword ||
2146               FormatTok->isOneOf(tok::numeric_constant, tok::l_square,
2147                                  tok::l_brace))) ||
2148             (FormatTok->Tok.isAnyIdentifier() &&
2149              std::binary_search(std::begin(FoundationIdentifiers),
2150                                 std::end(FoundationIdentifiers),
2151                                 FormatTok->TokenText)) ||
2152             FormatTok->is(TT_ObjCStringLiteral) ||
2153             FormatTok->isOneOf(Keywords.kw_NS_CLOSED_ENUM, Keywords.kw_NS_ENUM,
2154                                Keywords.kw_NS_OPTIONS, TT_ObjCBlockLBrace,
2155                                TT_ObjCBlockLParen, TT_ObjCDecl, TT_ObjCForIn,
2156                                TT_ObjCMethodExpr, TT_ObjCMethodSpecifier,
2157                                TT_ObjCProperty)) {
2158           LLVM_DEBUG(llvm::dbgs()
2159                      << "Detected ObjC at location "
2160                      << FormatTok->Tok.getLocation().printToString(
2161                             SourceManager)
2162                      << " token: " << FormatTok->TokenText << " token type: "
2163                      << getTokenTypeName(FormatTok->getType()) << "\n");
2164           return true;
2165         }
2166         if (guessIsObjC(SourceManager, Line->Children, Keywords))
2167           return true;
2168       }
2169     }
2170     return false;
2171   }
2172 
2173   bool IsObjC;
2174 };
2175 
2176 struct IncludeDirective {
2177   StringRef Filename;
2178   StringRef Text;
2179   unsigned Offset;
2180   int Category;
2181   int Priority;
2182 };
2183 
2184 struct JavaImportDirective {
2185   StringRef Identifier;
2186   StringRef Text;
2187   unsigned Offset;
2188   std::vector<StringRef> AssociatedCommentLines;
2189   bool IsStatic;
2190 };
2191 
2192 } // end anonymous namespace
2193 
2194 // Determines whether 'Ranges' intersects with ('Start', 'End').
2195 static bool affectsRange(ArrayRef<tooling::Range> Ranges, unsigned Start,
2196                          unsigned End) {
2197   for (auto Range : Ranges) {
2198     if (Range.getOffset() < End &&
2199         Range.getOffset() + Range.getLength() > Start)
2200       return true;
2201   }
2202   return false;
2203 }
2204 
2205 // Returns a pair (Index, OffsetToEOL) describing the position of the cursor
2206 // before sorting/deduplicating. Index is the index of the include under the
2207 // cursor in the original set of includes. If this include has duplicates, it is
2208 // the index of the first of the duplicates as the others are going to be
2209 // removed. OffsetToEOL describes the cursor's position relative to the end of
2210 // its current line.
2211 // If `Cursor` is not on any #include, `Index` will be UINT_MAX.
2212 static std::pair<unsigned, unsigned>
2213 FindCursorIndex(const SmallVectorImpl<IncludeDirective> &Includes,
2214                 const SmallVectorImpl<unsigned> &Indices, unsigned Cursor) {
2215   unsigned CursorIndex = UINT_MAX;
2216   unsigned OffsetToEOL = 0;
2217   for (int i = 0, e = Includes.size(); i != e; ++i) {
2218     unsigned Start = Includes[Indices[i]].Offset;
2219     unsigned End = Start + Includes[Indices[i]].Text.size();
2220     if (!(Cursor >= Start && Cursor < End))
2221       continue;
2222     CursorIndex = Indices[i];
2223     OffsetToEOL = End - Cursor;
2224     // Put the cursor on the only remaining #include among the duplicate
2225     // #includes.
2226     while (--i >= 0 && Includes[CursorIndex].Text == Includes[Indices[i]].Text)
2227       CursorIndex = i;
2228     break;
2229   }
2230   return std::make_pair(CursorIndex, OffsetToEOL);
2231 }
2232 
2233 // Replace all "\r\n" with "\n".
2234 std::string replaceCRLF(const std::string &Code) {
2235   std::string NewCode;
2236   size_t Pos = 0, LastPos = 0;
2237 
2238   do {
2239     Pos = Code.find("\r\n", LastPos);
2240     if (Pos == LastPos) {
2241       LastPos++;
2242       continue;
2243     }
2244     if (Pos == std::string::npos) {
2245       NewCode += Code.substr(LastPos);
2246       break;
2247     }
2248     NewCode += Code.substr(LastPos, Pos - LastPos) + "\n";
2249     LastPos = Pos + 2;
2250   } while (Pos != std::string::npos);
2251 
2252   return NewCode;
2253 }
2254 
2255 // Sorts and deduplicate a block of includes given by 'Includes' alphabetically
2256 // adding the necessary replacement to 'Replaces'. 'Includes' must be in strict
2257 // source order.
2258 // #include directives with the same text will be deduplicated, and only the
2259 // first #include in the duplicate #includes remains. If the `Cursor` is
2260 // provided and put on a deleted #include, it will be moved to the remaining
2261 // #include in the duplicate #includes.
2262 static void sortCppIncludes(const FormatStyle &Style,
2263                             const SmallVectorImpl<IncludeDirective> &Includes,
2264                             ArrayRef<tooling::Range> Ranges, StringRef FileName,
2265                             StringRef Code, tooling::Replacements &Replaces,
2266                             unsigned *Cursor) {
2267   tooling::IncludeCategoryManager Categories(Style.IncludeStyle, FileName);
2268   unsigned IncludesBeginOffset = Includes.front().Offset;
2269   unsigned IncludesEndOffset =
2270       Includes.back().Offset + Includes.back().Text.size();
2271   unsigned IncludesBlockSize = IncludesEndOffset - IncludesBeginOffset;
2272   if (!affectsRange(Ranges, IncludesBeginOffset, IncludesEndOffset))
2273     return;
2274   SmallVector<unsigned, 16> Indices;
2275   for (unsigned i = 0, e = Includes.size(); i != e; ++i) {
2276     Indices.push_back(i);
2277   }
2278 
2279   if (Style.SortIncludes == FormatStyle::SI_CaseInsensitive) {
2280     llvm::stable_sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
2281       const auto LHSFilenameLower = Includes[LHSI].Filename.lower();
2282       const auto RHSFilenameLower = Includes[RHSI].Filename.lower();
2283       return std::tie(Includes[LHSI].Priority, LHSFilenameLower,
2284                       Includes[LHSI].Filename) <
2285              std::tie(Includes[RHSI].Priority, RHSFilenameLower,
2286                       Includes[RHSI].Filename);
2287     });
2288   } else {
2289     llvm::stable_sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
2290       return std::tie(Includes[LHSI].Priority, Includes[LHSI].Filename) <
2291              std::tie(Includes[RHSI].Priority, Includes[RHSI].Filename);
2292     });
2293   }
2294 
2295   // The index of the include on which the cursor will be put after
2296   // sorting/deduplicating.
2297   unsigned CursorIndex;
2298   // The offset from cursor to the end of line.
2299   unsigned CursorToEOLOffset;
2300   if (Cursor)
2301     std::tie(CursorIndex, CursorToEOLOffset) =
2302         FindCursorIndex(Includes, Indices, *Cursor);
2303 
2304   // Deduplicate #includes.
2305   Indices.erase(std::unique(Indices.begin(), Indices.end(),
2306                             [&](unsigned LHSI, unsigned RHSI) {
2307                               return Includes[LHSI].Text.trim() ==
2308                                      Includes[RHSI].Text.trim();
2309                             }),
2310                 Indices.end());
2311 
2312   int CurrentCategory = Includes.front().Category;
2313 
2314   // If the #includes are out of order, we generate a single replacement fixing
2315   // the entire block. Otherwise, no replacement is generated.
2316   // In case Style.IncldueStyle.IncludeBlocks != IBS_Preserve, this check is not
2317   // enough as additional newlines might be added or removed across #include
2318   // blocks. This we handle below by generating the updated #imclude blocks and
2319   // comparing it to the original.
2320   if (Indices.size() == Includes.size() && llvm::is_sorted(Indices) &&
2321       Style.IncludeStyle.IncludeBlocks == tooling::IncludeStyle::IBS_Preserve)
2322     return;
2323 
2324   std::string result;
2325   for (unsigned Index : Indices) {
2326     if (!result.empty()) {
2327       result += "\n";
2328       if (Style.IncludeStyle.IncludeBlocks ==
2329               tooling::IncludeStyle::IBS_Regroup &&
2330           CurrentCategory != Includes[Index].Category)
2331         result += "\n";
2332     }
2333     result += Includes[Index].Text;
2334     if (Cursor && CursorIndex == Index)
2335       *Cursor = IncludesBeginOffset + result.size() - CursorToEOLOffset;
2336     CurrentCategory = Includes[Index].Category;
2337   }
2338 
2339   // If the #includes are out of order, we generate a single replacement fixing
2340   // the entire range of blocks. Otherwise, no replacement is generated.
2341   if (replaceCRLF(result) == replaceCRLF(std::string(Code.substr(
2342                                  IncludesBeginOffset, IncludesBlockSize))))
2343     return;
2344 
2345   auto Err = Replaces.add(tooling::Replacement(
2346       FileName, Includes.front().Offset, IncludesBlockSize, result));
2347   // FIXME: better error handling. For now, just skip the replacement for the
2348   // release version.
2349   if (Err) {
2350     llvm::errs() << llvm::toString(std::move(Err)) << "\n";
2351     assert(false);
2352   }
2353 }
2354 
2355 namespace {
2356 
2357 const char CppIncludeRegexPattern[] =
2358     R"(^[\t\ ]*#[\t\ ]*(import|include)[^"<]*(["<][^">]*[">]))";
2359 
2360 } // anonymous namespace
2361 
2362 tooling::Replacements sortCppIncludes(const FormatStyle &Style, StringRef Code,
2363                                       ArrayRef<tooling::Range> Ranges,
2364                                       StringRef FileName,
2365                                       tooling::Replacements &Replaces,
2366                                       unsigned *Cursor) {
2367   unsigned Prev = llvm::StringSwitch<size_t>(Code)
2368                       .StartsWith("\xEF\xBB\xBF", 3) // UTF-8 BOM
2369                       .Default(0);
2370   unsigned SearchFrom = 0;
2371   llvm::Regex IncludeRegex(CppIncludeRegexPattern);
2372   SmallVector<StringRef, 4> Matches;
2373   SmallVector<IncludeDirective, 16> IncludesInBlock;
2374 
2375   // In compiled files, consider the first #include to be the main #include of
2376   // the file if it is not a system #include. This ensures that the header
2377   // doesn't have hidden dependencies
2378   // (http://llvm.org/docs/CodingStandards.html#include-style).
2379   //
2380   // FIXME: Do some sanity checking, e.g. edit distance of the base name, to fix
2381   // cases where the first #include is unlikely to be the main header.
2382   tooling::IncludeCategoryManager Categories(Style.IncludeStyle, FileName);
2383   bool FirstIncludeBlock = true;
2384   bool MainIncludeFound = false;
2385   bool FormattingOff = false;
2386 
2387   for (;;) {
2388     auto Pos = Code.find('\n', SearchFrom);
2389     StringRef Line =
2390         Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
2391 
2392     StringRef Trimmed = Line.trim();
2393     if (Trimmed == "// clang-format off" || Trimmed == "/* clang-format off */")
2394       FormattingOff = true;
2395     else if (Trimmed == "// clang-format on" ||
2396              Trimmed == "/* clang-format on */")
2397       FormattingOff = false;
2398 
2399     const bool EmptyLineSkipped =
2400         Trimmed.empty() &&
2401         (Style.IncludeStyle.IncludeBlocks == tooling::IncludeStyle::IBS_Merge ||
2402          Style.IncludeStyle.IncludeBlocks ==
2403              tooling::IncludeStyle::IBS_Regroup);
2404 
2405     bool MergeWithNextLine = Trimmed.endswith("\\");
2406     if (!FormattingOff && !MergeWithNextLine) {
2407       if (IncludeRegex.match(Line, &Matches)) {
2408         StringRef IncludeName = Matches[2];
2409         int Category = Categories.getIncludePriority(
2410             IncludeName,
2411             /*CheckMainHeader=*/!MainIncludeFound && FirstIncludeBlock);
2412         int Priority = Categories.getSortIncludePriority(
2413             IncludeName, !MainIncludeFound && FirstIncludeBlock);
2414         if (Category == 0)
2415           MainIncludeFound = true;
2416         IncludesInBlock.push_back(
2417             {IncludeName, Line, Prev, Category, Priority});
2418       } else if (!IncludesInBlock.empty() && !EmptyLineSkipped) {
2419         sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Code,
2420                         Replaces, Cursor);
2421         IncludesInBlock.clear();
2422         if (Trimmed.startswith("#pragma hdrstop")) // Precompiled headers.
2423           FirstIncludeBlock = true;
2424         else
2425           FirstIncludeBlock = false;
2426       }
2427     }
2428     if (Pos == StringRef::npos || Pos + 1 == Code.size())
2429       break;
2430 
2431     if (!MergeWithNextLine)
2432       Prev = Pos + 1;
2433     SearchFrom = Pos + 1;
2434   }
2435   if (!IncludesInBlock.empty()) {
2436     sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Code, Replaces,
2437                     Cursor);
2438   }
2439   return Replaces;
2440 }
2441 
2442 // Returns group number to use as a first order sort on imports. Gives UINT_MAX
2443 // if the import does not match any given groups.
2444 static unsigned findJavaImportGroup(const FormatStyle &Style,
2445                                     StringRef ImportIdentifier) {
2446   unsigned LongestMatchIndex = UINT_MAX;
2447   unsigned LongestMatchLength = 0;
2448   for (unsigned I = 0; I < Style.JavaImportGroups.size(); I++) {
2449     std::string GroupPrefix = Style.JavaImportGroups[I];
2450     if (ImportIdentifier.startswith(GroupPrefix) &&
2451         GroupPrefix.length() > LongestMatchLength) {
2452       LongestMatchIndex = I;
2453       LongestMatchLength = GroupPrefix.length();
2454     }
2455   }
2456   return LongestMatchIndex;
2457 }
2458 
2459 // Sorts and deduplicates a block of includes given by 'Imports' based on
2460 // JavaImportGroups, then adding the necessary replacement to 'Replaces'.
2461 // Import declarations with the same text will be deduplicated. Between each
2462 // import group, a newline is inserted, and within each import group, a
2463 // lexicographic sort based on ASCII value is performed.
2464 static void sortJavaImports(const FormatStyle &Style,
2465                             const SmallVectorImpl<JavaImportDirective> &Imports,
2466                             ArrayRef<tooling::Range> Ranges, StringRef FileName,
2467                             StringRef Code, tooling::Replacements &Replaces) {
2468   unsigned ImportsBeginOffset = Imports.front().Offset;
2469   unsigned ImportsEndOffset =
2470       Imports.back().Offset + Imports.back().Text.size();
2471   unsigned ImportsBlockSize = ImportsEndOffset - ImportsBeginOffset;
2472   if (!affectsRange(Ranges, ImportsBeginOffset, ImportsEndOffset))
2473     return;
2474   SmallVector<unsigned, 16> Indices;
2475   SmallVector<unsigned, 16> JavaImportGroups;
2476   for (unsigned i = 0, e = Imports.size(); i != e; ++i) {
2477     Indices.push_back(i);
2478     JavaImportGroups.push_back(
2479         findJavaImportGroup(Style, Imports[i].Identifier));
2480   }
2481   bool StaticImportAfterNormalImport =
2482       Style.SortJavaStaticImport == FormatStyle::SJSIO_After;
2483   llvm::sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
2484     // Negating IsStatic to push static imports above non-static imports.
2485     return std::make_tuple(!Imports[LHSI].IsStatic ^
2486                                StaticImportAfterNormalImport,
2487                            JavaImportGroups[LHSI], Imports[LHSI].Identifier) <
2488            std::make_tuple(!Imports[RHSI].IsStatic ^
2489                                StaticImportAfterNormalImport,
2490                            JavaImportGroups[RHSI], Imports[RHSI].Identifier);
2491   });
2492 
2493   // Deduplicate imports.
2494   Indices.erase(std::unique(Indices.begin(), Indices.end(),
2495                             [&](unsigned LHSI, unsigned RHSI) {
2496                               return Imports[LHSI].Text == Imports[RHSI].Text;
2497                             }),
2498                 Indices.end());
2499 
2500   bool CurrentIsStatic = Imports[Indices.front()].IsStatic;
2501   unsigned CurrentImportGroup = JavaImportGroups[Indices.front()];
2502 
2503   std::string result;
2504   for (unsigned Index : Indices) {
2505     if (!result.empty()) {
2506       result += "\n";
2507       if (CurrentIsStatic != Imports[Index].IsStatic ||
2508           CurrentImportGroup != JavaImportGroups[Index])
2509         result += "\n";
2510     }
2511     for (StringRef CommentLine : Imports[Index].AssociatedCommentLines) {
2512       result += CommentLine;
2513       result += "\n";
2514     }
2515     result += Imports[Index].Text;
2516     CurrentIsStatic = Imports[Index].IsStatic;
2517     CurrentImportGroup = JavaImportGroups[Index];
2518   }
2519 
2520   // If the imports are out of order, we generate a single replacement fixing
2521   // the entire block. Otherwise, no replacement is generated.
2522   if (replaceCRLF(result) == replaceCRLF(std::string(Code.substr(
2523                                  Imports.front().Offset, ImportsBlockSize))))
2524     return;
2525 
2526   auto Err = Replaces.add(tooling::Replacement(FileName, Imports.front().Offset,
2527                                                ImportsBlockSize, result));
2528   // FIXME: better error handling. For now, just skip the replacement for the
2529   // release version.
2530   if (Err) {
2531     llvm::errs() << llvm::toString(std::move(Err)) << "\n";
2532     assert(false);
2533   }
2534 }
2535 
2536 namespace {
2537 
2538 const char JavaImportRegexPattern[] =
2539     "^[\t ]*import[\t ]+(static[\t ]*)?([^\t ]*)[\t ]*;";
2540 
2541 } // anonymous namespace
2542 
2543 tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code,
2544                                       ArrayRef<tooling::Range> Ranges,
2545                                       StringRef FileName,
2546                                       tooling::Replacements &Replaces) {
2547   unsigned Prev = 0;
2548   unsigned SearchFrom = 0;
2549   llvm::Regex ImportRegex(JavaImportRegexPattern);
2550   SmallVector<StringRef, 4> Matches;
2551   SmallVector<JavaImportDirective, 16> ImportsInBlock;
2552   std::vector<StringRef> AssociatedCommentLines;
2553 
2554   bool FormattingOff = false;
2555 
2556   for (;;) {
2557     auto Pos = Code.find('\n', SearchFrom);
2558     StringRef Line =
2559         Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
2560 
2561     StringRef Trimmed = Line.trim();
2562     if (Trimmed == "// clang-format off")
2563       FormattingOff = true;
2564     else if (Trimmed == "// clang-format on")
2565       FormattingOff = false;
2566 
2567     if (ImportRegex.match(Line, &Matches)) {
2568       if (FormattingOff) {
2569         // If at least one import line has formatting turned off, turn off
2570         // formatting entirely.
2571         return Replaces;
2572       }
2573       StringRef Static = Matches[1];
2574       StringRef Identifier = Matches[2];
2575       bool IsStatic = false;
2576       if (Static.contains("static")) {
2577         IsStatic = true;
2578       }
2579       ImportsInBlock.push_back(
2580           {Identifier, Line, Prev, AssociatedCommentLines, IsStatic});
2581       AssociatedCommentLines.clear();
2582     } else if (Trimmed.size() > 0 && !ImportsInBlock.empty()) {
2583       // Associating comments within the imports with the nearest import below
2584       AssociatedCommentLines.push_back(Line);
2585     }
2586     Prev = Pos + 1;
2587     if (Pos == StringRef::npos || Pos + 1 == Code.size())
2588       break;
2589     SearchFrom = Pos + 1;
2590   }
2591   if (!ImportsInBlock.empty())
2592     sortJavaImports(Style, ImportsInBlock, Ranges, FileName, Code, Replaces);
2593   return Replaces;
2594 }
2595 
2596 bool isMpegTS(StringRef Code) {
2597   // MPEG transport streams use the ".ts" file extension. clang-format should
2598   // not attempt to format those. MPEG TS' frame format starts with 0x47 every
2599   // 189 bytes - detect that and return.
2600   return Code.size() > 188 && Code[0] == 0x47 && Code[188] == 0x47;
2601 }
2602 
2603 bool isLikelyXml(StringRef Code) { return Code.ltrim().startswith("<"); }
2604 
2605 tooling::Replacements sortIncludes(const FormatStyle &Style, StringRef Code,
2606                                    ArrayRef<tooling::Range> Ranges,
2607                                    StringRef FileName, unsigned *Cursor) {
2608   tooling::Replacements Replaces;
2609   if (!Style.SortIncludes || Style.DisableFormat)
2610     return Replaces;
2611   if (isLikelyXml(Code))
2612     return Replaces;
2613   if (Style.Language == FormatStyle::LanguageKind::LK_JavaScript &&
2614       isMpegTS(Code))
2615     return Replaces;
2616   if (Style.Language == FormatStyle::LanguageKind::LK_JavaScript)
2617     return sortJavaScriptImports(Style, Code, Ranges, FileName);
2618   if (Style.Language == FormatStyle::LanguageKind::LK_Java)
2619     return sortJavaImports(Style, Code, Ranges, FileName, Replaces);
2620   sortCppIncludes(Style, Code, Ranges, FileName, Replaces, Cursor);
2621   return Replaces;
2622 }
2623 
2624 template <typename T>
2625 static llvm::Expected<tooling::Replacements>
2626 processReplacements(T ProcessFunc, StringRef Code,
2627                     const tooling::Replacements &Replaces,
2628                     const FormatStyle &Style) {
2629   if (Replaces.empty())
2630     return tooling::Replacements();
2631 
2632   auto NewCode = applyAllReplacements(Code, Replaces);
2633   if (!NewCode)
2634     return NewCode.takeError();
2635   std::vector<tooling::Range> ChangedRanges = Replaces.getAffectedRanges();
2636   StringRef FileName = Replaces.begin()->getFilePath();
2637 
2638   tooling::Replacements FormatReplaces =
2639       ProcessFunc(Style, *NewCode, ChangedRanges, FileName);
2640 
2641   return Replaces.merge(FormatReplaces);
2642 }
2643 
2644 llvm::Expected<tooling::Replacements>
2645 formatReplacements(StringRef Code, const tooling::Replacements &Replaces,
2646                    const FormatStyle &Style) {
2647   // We need to use lambda function here since there are two versions of
2648   // `sortIncludes`.
2649   auto SortIncludes = [](const FormatStyle &Style, StringRef Code,
2650                          std::vector<tooling::Range> Ranges,
2651                          StringRef FileName) -> tooling::Replacements {
2652     return sortIncludes(Style, Code, Ranges, FileName);
2653   };
2654   auto SortedReplaces =
2655       processReplacements(SortIncludes, Code, Replaces, Style);
2656   if (!SortedReplaces)
2657     return SortedReplaces.takeError();
2658 
2659   // We need to use lambda function here since there are two versions of
2660   // `reformat`.
2661   auto Reformat = [](const FormatStyle &Style, StringRef Code,
2662                      std::vector<tooling::Range> Ranges,
2663                      StringRef FileName) -> tooling::Replacements {
2664     return reformat(Style, Code, Ranges, FileName);
2665   };
2666   return processReplacements(Reformat, Code, *SortedReplaces, Style);
2667 }
2668 
2669 namespace {
2670 
2671 inline bool isHeaderInsertion(const tooling::Replacement &Replace) {
2672   return Replace.getOffset() == UINT_MAX && Replace.getLength() == 0 &&
2673          llvm::Regex(CppIncludeRegexPattern)
2674              .match(Replace.getReplacementText());
2675 }
2676 
2677 inline bool isHeaderDeletion(const tooling::Replacement &Replace) {
2678   return Replace.getOffset() == UINT_MAX && Replace.getLength() == 1;
2679 }
2680 
2681 // FIXME: insert empty lines between newly created blocks.
2682 tooling::Replacements
2683 fixCppIncludeInsertions(StringRef Code, const tooling::Replacements &Replaces,
2684                         const FormatStyle &Style) {
2685   if (!Style.isCpp())
2686     return Replaces;
2687 
2688   tooling::Replacements HeaderInsertions;
2689   std::set<llvm::StringRef> HeadersToDelete;
2690   tooling::Replacements Result;
2691   for (const auto &R : Replaces) {
2692     if (isHeaderInsertion(R)) {
2693       // Replacements from \p Replaces must be conflict-free already, so we can
2694       // simply consume the error.
2695       llvm::consumeError(HeaderInsertions.add(R));
2696     } else if (isHeaderDeletion(R)) {
2697       HeadersToDelete.insert(R.getReplacementText());
2698     } else if (R.getOffset() == UINT_MAX) {
2699       llvm::errs() << "Insertions other than header #include insertion are "
2700                       "not supported! "
2701                    << R.getReplacementText() << "\n";
2702     } else {
2703       llvm::consumeError(Result.add(R));
2704     }
2705   }
2706   if (HeaderInsertions.empty() && HeadersToDelete.empty())
2707     return Replaces;
2708 
2709   StringRef FileName = Replaces.begin()->getFilePath();
2710   tooling::HeaderIncludes Includes(FileName, Code, Style.IncludeStyle);
2711 
2712   for (const auto &Header : HeadersToDelete) {
2713     tooling::Replacements Replaces =
2714         Includes.remove(Header.trim("\"<>"), Header.startswith("<"));
2715     for (const auto &R : Replaces) {
2716       auto Err = Result.add(R);
2717       if (Err) {
2718         // Ignore the deletion on conflict.
2719         llvm::errs() << "Failed to add header deletion replacement for "
2720                      << Header << ": " << llvm::toString(std::move(Err))
2721                      << "\n";
2722       }
2723     }
2724   }
2725 
2726   llvm::Regex IncludeRegex = llvm::Regex(CppIncludeRegexPattern);
2727   llvm::SmallVector<StringRef, 4> Matches;
2728   for (const auto &R : HeaderInsertions) {
2729     auto IncludeDirective = R.getReplacementText();
2730     bool Matched = IncludeRegex.match(IncludeDirective, &Matches);
2731     assert(Matched && "Header insertion replacement must have replacement text "
2732                       "'#include ...'");
2733     (void)Matched;
2734     auto IncludeName = Matches[2];
2735     auto Replace =
2736         Includes.insert(IncludeName.trim("\"<>"), IncludeName.startswith("<"));
2737     if (Replace) {
2738       auto Err = Result.add(*Replace);
2739       if (Err) {
2740         llvm::consumeError(std::move(Err));
2741         unsigned NewOffset =
2742             Result.getShiftedCodePosition(Replace->getOffset());
2743         auto Shifted = tooling::Replacement(FileName, NewOffset, 0,
2744                                             Replace->getReplacementText());
2745         Result = Result.merge(tooling::Replacements(Shifted));
2746       }
2747     }
2748   }
2749   return Result;
2750 }
2751 
2752 } // anonymous namespace
2753 
2754 llvm::Expected<tooling::Replacements>
2755 cleanupAroundReplacements(StringRef Code, const tooling::Replacements &Replaces,
2756                           const FormatStyle &Style) {
2757   // We need to use lambda function here since there are two versions of
2758   // `cleanup`.
2759   auto Cleanup = [](const FormatStyle &Style, StringRef Code,
2760                     std::vector<tooling::Range> Ranges,
2761                     StringRef FileName) -> tooling::Replacements {
2762     return cleanup(Style, Code, Ranges, FileName);
2763   };
2764   // Make header insertion replacements insert new headers into correct blocks.
2765   tooling::Replacements NewReplaces =
2766       fixCppIncludeInsertions(Code, Replaces, Style);
2767   return processReplacements(Cleanup, Code, NewReplaces, Style);
2768 }
2769 
2770 namespace internal {
2771 std::pair<tooling::Replacements, unsigned>
2772 reformat(const FormatStyle &Style, StringRef Code,
2773          ArrayRef<tooling::Range> Ranges, unsigned FirstStartColumn,
2774          unsigned NextStartColumn, unsigned LastStartColumn, StringRef FileName,
2775          FormattingAttemptStatus *Status) {
2776   FormatStyle Expanded = expandPresets(Style);
2777   if (Expanded.DisableFormat)
2778     return {tooling::Replacements(), 0};
2779   if (isLikelyXml(Code))
2780     return {tooling::Replacements(), 0};
2781   if (Expanded.Language == FormatStyle::LK_JavaScript && isMpegTS(Code))
2782     return {tooling::Replacements(), 0};
2783 
2784   typedef std::function<std::pair<tooling::Replacements, unsigned>(
2785       const Environment &)>
2786       AnalyzerPass;
2787   SmallVector<AnalyzerPass, 4> Passes;
2788 
2789   if (Style.Language == FormatStyle::LK_Cpp) {
2790     if (Style.FixNamespaceComments)
2791       Passes.emplace_back([&](const Environment &Env) {
2792         return NamespaceEndCommentsFixer(Env, Expanded).process();
2793       });
2794 
2795     if (Style.SortUsingDeclarations)
2796       Passes.emplace_back([&](const Environment &Env) {
2797         return UsingDeclarationsSorter(Env, Expanded).process();
2798       });
2799   }
2800 
2801   if (Style.Language == FormatStyle::LK_JavaScript &&
2802       Style.JavaScriptQuotes != FormatStyle::JSQS_Leave)
2803     Passes.emplace_back([&](const Environment &Env) {
2804       return JavaScriptRequoter(Env, Expanded).process();
2805     });
2806 
2807   Passes.emplace_back([&](const Environment &Env) {
2808     return Formatter(Env, Expanded, Status).process();
2809   });
2810 
2811   if (Style.Language == FormatStyle::LK_JavaScript &&
2812       Style.InsertTrailingCommas == FormatStyle::TCS_Wrapped)
2813     Passes.emplace_back([&](const Environment &Env) {
2814       return TrailingCommaInserter(Env, Expanded).process();
2815     });
2816 
2817   auto Env =
2818       std::make_unique<Environment>(Code, FileName, Ranges, FirstStartColumn,
2819                                     NextStartColumn, LastStartColumn);
2820   llvm::Optional<std::string> CurrentCode = None;
2821   tooling::Replacements Fixes;
2822   unsigned Penalty = 0;
2823   for (size_t I = 0, E = Passes.size(); I < E; ++I) {
2824     std::pair<tooling::Replacements, unsigned> PassFixes = Passes[I](*Env);
2825     auto NewCode = applyAllReplacements(
2826         CurrentCode ? StringRef(*CurrentCode) : Code, PassFixes.first);
2827     if (NewCode) {
2828       Fixes = Fixes.merge(PassFixes.first);
2829       Penalty += PassFixes.second;
2830       if (I + 1 < E) {
2831         CurrentCode = std::move(*NewCode);
2832         Env = std::make_unique<Environment>(
2833             *CurrentCode, FileName,
2834             tooling::calculateRangesAfterReplacements(Fixes, Ranges),
2835             FirstStartColumn, NextStartColumn, LastStartColumn);
2836       }
2837     }
2838   }
2839 
2840   return {Fixes, Penalty};
2841 }
2842 } // namespace internal
2843 
2844 tooling::Replacements reformat(const FormatStyle &Style, StringRef Code,
2845                                ArrayRef<tooling::Range> Ranges,
2846                                StringRef FileName,
2847                                FormattingAttemptStatus *Status) {
2848   return internal::reformat(Style, Code, Ranges,
2849                             /*FirstStartColumn=*/0,
2850                             /*NextStartColumn=*/0,
2851                             /*LastStartColumn=*/0, FileName, Status)
2852       .first;
2853 }
2854 
2855 tooling::Replacements cleanup(const FormatStyle &Style, StringRef Code,
2856                               ArrayRef<tooling::Range> Ranges,
2857                               StringRef FileName) {
2858   // cleanups only apply to C++ (they mostly concern ctor commas etc.)
2859   if (Style.Language != FormatStyle::LK_Cpp)
2860     return tooling::Replacements();
2861   return Cleaner(Environment(Code, FileName, Ranges), Style).process().first;
2862 }
2863 
2864 tooling::Replacements reformat(const FormatStyle &Style, StringRef Code,
2865                                ArrayRef<tooling::Range> Ranges,
2866                                StringRef FileName, bool *IncompleteFormat) {
2867   FormattingAttemptStatus Status;
2868   auto Result = reformat(Style, Code, Ranges, FileName, &Status);
2869   if (!Status.FormatComplete)
2870     *IncompleteFormat = true;
2871   return Result;
2872 }
2873 
2874 tooling::Replacements fixNamespaceEndComments(const FormatStyle &Style,
2875                                               StringRef Code,
2876                                               ArrayRef<tooling::Range> Ranges,
2877                                               StringRef FileName) {
2878   return NamespaceEndCommentsFixer(Environment(Code, FileName, Ranges), Style)
2879       .process()
2880       .first;
2881 }
2882 
2883 tooling::Replacements sortUsingDeclarations(const FormatStyle &Style,
2884                                             StringRef Code,
2885                                             ArrayRef<tooling::Range> Ranges,
2886                                             StringRef FileName) {
2887   return UsingDeclarationsSorter(Environment(Code, FileName, Ranges), Style)
2888       .process()
2889       .first;
2890 }
2891 
2892 LangOptions getFormattingLangOpts(const FormatStyle &Style) {
2893   LangOptions LangOpts;
2894 
2895   FormatStyle::LanguageStandard LexingStd = Style.Standard;
2896   if (LexingStd == FormatStyle::LS_Auto)
2897     LexingStd = FormatStyle::LS_Latest;
2898   if (LexingStd == FormatStyle::LS_Latest)
2899     LexingStd = FormatStyle::LS_Cpp20;
2900   LangOpts.CPlusPlus = 1;
2901   LangOpts.CPlusPlus11 = LexingStd >= FormatStyle::LS_Cpp11;
2902   LangOpts.CPlusPlus14 = LexingStd >= FormatStyle::LS_Cpp14;
2903   LangOpts.CPlusPlus17 = LexingStd >= FormatStyle::LS_Cpp17;
2904   LangOpts.CPlusPlus20 = LexingStd >= FormatStyle::LS_Cpp20;
2905   LangOpts.Char8 = LexingStd >= FormatStyle::LS_Cpp20;
2906 
2907   LangOpts.LineComment = 1;
2908   bool AlternativeOperators = Style.isCpp();
2909   LangOpts.CXXOperatorNames = AlternativeOperators ? 1 : 0;
2910   LangOpts.Bool = 1;
2911   LangOpts.ObjC = 1;
2912   LangOpts.MicrosoftExt = 1;    // To get kw___try, kw___finally.
2913   LangOpts.DeclSpecKeyword = 1; // To get __declspec.
2914   LangOpts.C99 = 1; // To get kw_restrict for non-underscore-prefixed restrict.
2915   return LangOpts;
2916 }
2917 
2918 const char *StyleOptionHelpDescription =
2919     "Coding style, currently supports:\n"
2920     "  LLVM, GNU, Google, Chromium, Microsoft, Mozilla, WebKit.\n"
2921     "Use -style=file to load style configuration from\n"
2922     ".clang-format file located in one of the parent\n"
2923     "directories of the source file (or current\n"
2924     "directory for stdin).\n"
2925     "Use -style=\"{key: value, ...}\" to set specific\n"
2926     "parameters, e.g.:\n"
2927     "  -style=\"{BasedOnStyle: llvm, IndentWidth: 8}\"";
2928 
2929 static FormatStyle::LanguageKind getLanguageByFileName(StringRef FileName) {
2930   if (FileName.endswith(".java"))
2931     return FormatStyle::LK_Java;
2932   if (FileName.endswith_lower(".js") || FileName.endswith_lower(".mjs") ||
2933       FileName.endswith_lower(".ts"))
2934     return FormatStyle::LK_JavaScript; // (module) JavaScript or TypeScript.
2935   if (FileName.endswith(".m") || FileName.endswith(".mm"))
2936     return FormatStyle::LK_ObjC;
2937   if (FileName.endswith_lower(".proto") ||
2938       FileName.endswith_lower(".protodevel"))
2939     return FormatStyle::LK_Proto;
2940   if (FileName.endswith_lower(".textpb") ||
2941       FileName.endswith_lower(".pb.txt") ||
2942       FileName.endswith_lower(".textproto") ||
2943       FileName.endswith_lower(".asciipb"))
2944     return FormatStyle::LK_TextProto;
2945   if (FileName.endswith_lower(".td"))
2946     return FormatStyle::LK_TableGen;
2947   if (FileName.endswith_lower(".cs"))
2948     return FormatStyle::LK_CSharp;
2949   return FormatStyle::LK_Cpp;
2950 }
2951 
2952 FormatStyle::LanguageKind guessLanguage(StringRef FileName, StringRef Code) {
2953   const auto GuessedLanguage = getLanguageByFileName(FileName);
2954   if (GuessedLanguage == FormatStyle::LK_Cpp) {
2955     auto Extension = llvm::sys::path::extension(FileName);
2956     // If there's no file extension (or it's .h), we need to check the contents
2957     // of the code to see if it contains Objective-C.
2958     if (Extension.empty() || Extension == ".h") {
2959       auto NonEmptyFileName = FileName.empty() ? "guess.h" : FileName;
2960       Environment Env(Code, NonEmptyFileName, /*Ranges=*/{});
2961       ObjCHeaderStyleGuesser Guesser(Env, getLLVMStyle());
2962       Guesser.process();
2963       if (Guesser.isObjC())
2964         return FormatStyle::LK_ObjC;
2965     }
2966   }
2967   return GuessedLanguage;
2968 }
2969 
2970 const char *DefaultFormatStyle = "file";
2971 
2972 const char *DefaultFallbackStyle = "LLVM";
2973 
2974 llvm::Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName,
2975                                      StringRef FallbackStyleName,
2976                                      StringRef Code, llvm::vfs::FileSystem *FS,
2977                                      bool AllowUnknownOptions) {
2978   if (!FS) {
2979     FS = llvm::vfs::getRealFileSystem().get();
2980   }
2981   FormatStyle Style = getLLVMStyle(guessLanguage(FileName, Code));
2982 
2983   FormatStyle FallbackStyle = getNoStyle();
2984   if (!getPredefinedStyle(FallbackStyleName, Style.Language, &FallbackStyle))
2985     return make_string_error("Invalid fallback style \"" + FallbackStyleName);
2986 
2987   llvm::SmallVector<std::unique_ptr<llvm::MemoryBuffer>, 1>
2988       ChildFormatTextToApply;
2989 
2990   if (StyleName.startswith("{")) {
2991     // Parse YAML/JSON style from the command line.
2992     StringRef Source = "<command-line>";
2993     if (std::error_code ec =
2994             parseConfiguration(llvm::MemoryBufferRef(StyleName, Source), &Style,
2995                                AllowUnknownOptions))
2996       return make_string_error("Error parsing -style: " + ec.message());
2997     if (Style.InheritsParentConfig)
2998       ChildFormatTextToApply.emplace_back(
2999           llvm::MemoryBuffer::getMemBuffer(StyleName, Source, false));
3000     else
3001       return Style;
3002   }
3003 
3004   // If the style inherits the parent configuration it is a command line
3005   // configuration, which wants to inherit, so we have to skip the check of the
3006   // StyleName.
3007   if (!Style.InheritsParentConfig && !StyleName.equals_lower("file")) {
3008     if (!getPredefinedStyle(StyleName, Style.Language, &Style))
3009       return make_string_error("Invalid value for -style");
3010     if (!Style.InheritsParentConfig)
3011       return Style;
3012   }
3013 
3014   // Reset possible inheritance
3015   Style.InheritsParentConfig = false;
3016 
3017   // Look for .clang-format/_clang-format file in the file's parent directories.
3018   SmallString<128> UnsuitableConfigFiles;
3019   SmallString<128> Path(FileName);
3020   if (std::error_code EC = FS->makeAbsolute(Path))
3021     return make_string_error(EC.message());
3022 
3023   llvm::SmallVector<std::string, 2> FilesToLookFor;
3024   FilesToLookFor.push_back(".clang-format");
3025   FilesToLookFor.push_back("_clang-format");
3026 
3027   auto dropDiagnosticHandler = [](const llvm::SMDiagnostic &, void *) {};
3028 
3029   for (StringRef Directory = Path; !Directory.empty();
3030        Directory = llvm::sys::path::parent_path(Directory)) {
3031 
3032     auto Status = FS->status(Directory);
3033     if (!Status ||
3034         Status->getType() != llvm::sys::fs::file_type::directory_file) {
3035       continue;
3036     }
3037 
3038     for (const auto &F : FilesToLookFor) {
3039       SmallString<128> ConfigFile(Directory);
3040 
3041       llvm::sys::path::append(ConfigFile, F);
3042       LLVM_DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n");
3043 
3044       Status = FS->status(ConfigFile.str());
3045 
3046       if (Status &&
3047           (Status->getType() == llvm::sys::fs::file_type::regular_file)) {
3048         llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
3049             FS->getBufferForFile(ConfigFile.str());
3050         if (std::error_code EC = Text.getError())
3051           return make_string_error(EC.message());
3052         if (std::error_code ec =
3053                 parseConfiguration(*Text.get(), &Style, AllowUnknownOptions)) {
3054           if (ec == ParseError::Unsuitable) {
3055             if (!UnsuitableConfigFiles.empty())
3056               UnsuitableConfigFiles.append(", ");
3057             UnsuitableConfigFiles.append(ConfigFile);
3058             continue;
3059           }
3060           return make_string_error("Error reading " + ConfigFile + ": " +
3061                                    ec.message());
3062         }
3063         LLVM_DEBUG(llvm::dbgs()
3064                    << "Using configuration file " << ConfigFile << "\n");
3065 
3066         if (!Style.InheritsParentConfig) {
3067           if (ChildFormatTextToApply.empty())
3068             return Style;
3069 
3070           LLVM_DEBUG(llvm::dbgs() << "Applying child configurations\n");
3071 
3072           for (const auto &MemBuf : llvm::reverse(ChildFormatTextToApply)) {
3073             auto Ec = parseConfiguration(*MemBuf, &Style, AllowUnknownOptions,
3074                                          dropDiagnosticHandler);
3075             // It was already correctly parsed.
3076             assert(!Ec);
3077             static_cast<void>(Ec);
3078           }
3079 
3080           return Style;
3081         }
3082 
3083         LLVM_DEBUG(llvm::dbgs() << "Inherits parent configuration\n");
3084 
3085         // Reset inheritance of style
3086         Style.InheritsParentConfig = false;
3087 
3088         ChildFormatTextToApply.emplace_back(std::move(*Text));
3089 
3090         // Breaking out of the inner loop, since we don't want to parse
3091         // .clang-format AND _clang-format, if both exist. Then we continue the
3092         // inner loop (parent directories) in search for the parent
3093         // configuration.
3094         break;
3095       }
3096     }
3097   }
3098   if (!UnsuitableConfigFiles.empty())
3099     return make_string_error("Configuration file(s) do(es) not support " +
3100                              getLanguageName(Style.Language) + ": " +
3101                              UnsuitableConfigFiles);
3102 
3103   if (!ChildFormatTextToApply.empty()) {
3104     assert(ChildFormatTextToApply.size() == 1);
3105 
3106     LLVM_DEBUG(llvm::dbgs()
3107                << "Applying child configuration on fallback style\n");
3108 
3109     auto Ec =
3110         parseConfiguration(*ChildFormatTextToApply.front(), &FallbackStyle,
3111                            AllowUnknownOptions, dropDiagnosticHandler);
3112     // It was already correctly parsed.
3113     assert(!Ec);
3114     static_cast<void>(Ec);
3115   }
3116 
3117   return FallbackStyle;
3118 }
3119 
3120 } // namespace format
3121 } // namespace clang
3122