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