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