Coverage Report

Created: 2020-02-25 14:32

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