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