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