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