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 }, 719 /*EnclosingFunctionNames=*/ 720 {}, 721 /*CanonicalDelimiter=*/"", 722 /*BasedOnStyle=*/"google", 723 }}; 724 GoogleStyle.SpacesBeforeTrailingComments = 2; 725 GoogleStyle.Standard = FormatStyle::LS_Auto; 726 727 GoogleStyle.PenaltyReturnTypeOnItsOwnLine = 200; 728 GoogleStyle.PenaltyBreakBeforeFirstCallParameter = 1; 729 730 if (Language == FormatStyle::LK_Java) { 731 GoogleStyle.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; 732 GoogleStyle.AlignOperands = false; 733 GoogleStyle.AlignTrailingComments = false; 734 GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty; 735 GoogleStyle.AllowShortIfStatementsOnASingleLine = false; 736 GoogleStyle.AlwaysBreakBeforeMultilineStrings = false; 737 GoogleStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment; 738 GoogleStyle.ColumnLimit = 100; 739 GoogleStyle.SpaceAfterCStyleCast = true; 740 GoogleStyle.SpacesBeforeTrailingComments = 1; 741 } else if (Language == FormatStyle::LK_JavaScript) { 742 GoogleStyle.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; 743 GoogleStyle.AlignOperands = false; 744 GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty; 745 GoogleStyle.AlwaysBreakBeforeMultilineStrings = false; 746 GoogleStyle.BreakBeforeTernaryOperators = false; 747 // taze:, triple slash directives (`/// <...`), @tag followed by { for a lot 748 // of JSDoc tags, and @see, which is commonly followed by overlong URLs. 749 GoogleStyle.CommentPragmas = 750 "(taze:|^/[ \t]*<|(@[A-Za-z_0-9-]+[ \\t]*{)|@see)"; 751 GoogleStyle.MaxEmptyLinesToKeep = 3; 752 GoogleStyle.NamespaceIndentation = FormatStyle::NI_All; 753 GoogleStyle.SpacesInContainerLiterals = false; 754 GoogleStyle.JavaScriptQuotes = FormatStyle::JSQS_Single; 755 GoogleStyle.JavaScriptWrapImports = false; 756 } else if (Language == FormatStyle::LK_Proto) { 757 GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None; 758 GoogleStyle.SpacesInContainerLiterals = false; 759 GoogleStyle.Cpp11BracedListStyle = false; 760 // This affects protocol buffer options specifications and text protos. 761 // Text protos are currently mostly formatted inside C++ raw string literals 762 // and often the current breaking behavior of string literals is not 763 // beneficial there. Investigate turning this on once proper string reflow 764 // has been implemented. 765 GoogleStyle.BreakStringLiterals = false; 766 } else if (Language == FormatStyle::LK_ObjC) { 767 GoogleStyle.ColumnLimit = 100; 768 } 769 770 return GoogleStyle; 771 } 772 773 FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language) { 774 FormatStyle ChromiumStyle = getGoogleStyle(Language); 775 if (Language == FormatStyle::LK_Java) { 776 ChromiumStyle.AllowShortIfStatementsOnASingleLine = true; 777 ChromiumStyle.BreakAfterJavaFieldAnnotations = true; 778 ChromiumStyle.ContinuationIndentWidth = 8; 779 ChromiumStyle.IndentWidth = 4; 780 } else if (Language == FormatStyle::LK_JavaScript) { 781 ChromiumStyle.AllowShortIfStatementsOnASingleLine = false; 782 ChromiumStyle.AllowShortLoopsOnASingleLine = false; 783 } else { 784 ChromiumStyle.AllowAllParametersOfDeclarationOnNextLine = false; 785 ChromiumStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline; 786 ChromiumStyle.AllowShortIfStatementsOnASingleLine = false; 787 ChromiumStyle.AllowShortLoopsOnASingleLine = false; 788 ChromiumStyle.BinPackParameters = false; 789 ChromiumStyle.DerivePointerAlignment = false; 790 if (Language == FormatStyle::LK_ObjC) 791 ChromiumStyle.ColumnLimit = 80; 792 } 793 return ChromiumStyle; 794 } 795 796 FormatStyle getMozillaStyle() { 797 FormatStyle MozillaStyle = getLLVMStyle(); 798 MozillaStyle.AllowAllParametersOfDeclarationOnNextLine = false; 799 MozillaStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline; 800 MozillaStyle.AlwaysBreakAfterReturnType = FormatStyle::RTBS_TopLevel; 801 MozillaStyle.AlwaysBreakAfterDefinitionReturnType = 802 FormatStyle::DRTBS_TopLevel; 803 MozillaStyle.AlwaysBreakTemplateDeclarations = true; 804 MozillaStyle.BinPackParameters = false; 805 MozillaStyle.BinPackArguments = false; 806 MozillaStyle.BreakBeforeBraces = FormatStyle::BS_Mozilla; 807 MozillaStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma; 808 MozillaStyle.BreakBeforeInheritanceComma = true; 809 MozillaStyle.ConstructorInitializerIndentWidth = 2; 810 MozillaStyle.ContinuationIndentWidth = 2; 811 MozillaStyle.Cpp11BracedListStyle = false; 812 MozillaStyle.FixNamespaceComments = false; 813 MozillaStyle.IndentCaseLabels = true; 814 MozillaStyle.ObjCSpaceAfterProperty = true; 815 MozillaStyle.ObjCSpaceBeforeProtocolList = false; 816 MozillaStyle.PenaltyReturnTypeOnItsOwnLine = 200; 817 MozillaStyle.PointerAlignment = FormatStyle::PAS_Left; 818 MozillaStyle.SpaceAfterTemplateKeyword = false; 819 return MozillaStyle; 820 } 821 822 FormatStyle getWebKitStyle() { 823 FormatStyle Style = getLLVMStyle(); 824 Style.AccessModifierOffset = -4; 825 Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; 826 Style.AlignOperands = false; 827 Style.AlignTrailingComments = false; 828 Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All; 829 Style.BreakBeforeBraces = FormatStyle::BS_WebKit; 830 Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma; 831 Style.Cpp11BracedListStyle = false; 832 Style.ColumnLimit = 0; 833 Style.FixNamespaceComments = false; 834 Style.IndentWidth = 4; 835 Style.NamespaceIndentation = FormatStyle::NI_Inner; 836 Style.ObjCBlockIndentWidth = 4; 837 Style.ObjCSpaceAfterProperty = true; 838 Style.PointerAlignment = FormatStyle::PAS_Left; 839 return Style; 840 } 841 842 FormatStyle getGNUStyle() { 843 FormatStyle Style = getLLVMStyle(); 844 Style.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_All; 845 Style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_AllDefinitions; 846 Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All; 847 Style.BreakBeforeBraces = FormatStyle::BS_GNU; 848 Style.BreakBeforeTernaryOperators = true; 849 Style.Cpp11BracedListStyle = false; 850 Style.ColumnLimit = 79; 851 Style.FixNamespaceComments = false; 852 Style.SpaceBeforeParens = FormatStyle::SBPO_Always; 853 Style.Standard = FormatStyle::LS_Cpp03; 854 return Style; 855 } 856 857 FormatStyle getNoStyle() { 858 FormatStyle NoStyle = getLLVMStyle(); 859 NoStyle.DisableFormat = true; 860 NoStyle.SortIncludes = false; 861 NoStyle.SortUsingDeclarations = false; 862 return NoStyle; 863 } 864 865 bool getPredefinedStyle(StringRef Name, FormatStyle::LanguageKind Language, 866 FormatStyle *Style) { 867 if (Name.equals_lower("llvm")) { 868 *Style = getLLVMStyle(); 869 } else if (Name.equals_lower("chromium")) { 870 *Style = getChromiumStyle(Language); 871 } else if (Name.equals_lower("mozilla")) { 872 *Style = getMozillaStyle(); 873 } else if (Name.equals_lower("google")) { 874 *Style = getGoogleStyle(Language); 875 } else if (Name.equals_lower("webkit")) { 876 *Style = getWebKitStyle(); 877 } else if (Name.equals_lower("gnu")) { 878 *Style = getGNUStyle(); 879 } else if (Name.equals_lower("none")) { 880 *Style = getNoStyle(); 881 } else { 882 return false; 883 } 884 885 Style->Language = Language; 886 return true; 887 } 888 889 std::error_code parseConfiguration(StringRef Text, FormatStyle *Style) { 890 assert(Style); 891 FormatStyle::LanguageKind Language = Style->Language; 892 assert(Language != FormatStyle::LK_None); 893 if (Text.trim().empty()) 894 return make_error_code(ParseError::Error); 895 Style->StyleSet.Clear(); 896 std::vector<FormatStyle> Styles; 897 llvm::yaml::Input Input(Text); 898 // DocumentListTraits<vector<FormatStyle>> uses the context to get default 899 // values for the fields, keys for which are missing from the configuration. 900 // Mapping also uses the context to get the language to find the correct 901 // base style. 902 Input.setContext(Style); 903 Input >> Styles; 904 if (Input.error()) 905 return Input.error(); 906 907 for (unsigned i = 0; i < Styles.size(); ++i) { 908 // Ensures that only the first configuration can skip the Language option. 909 if (Styles[i].Language == FormatStyle::LK_None && i != 0) 910 return make_error_code(ParseError::Error); 911 // Ensure that each language is configured at most once. 912 for (unsigned j = 0; j < i; ++j) { 913 if (Styles[i].Language == Styles[j].Language) { 914 DEBUG(llvm::dbgs() 915 << "Duplicate languages in the config file on positions " << j 916 << " and " << i << "\n"); 917 return make_error_code(ParseError::Error); 918 } 919 } 920 } 921 // Look for a suitable configuration starting from the end, so we can 922 // find the configuration for the specific language first, and the default 923 // configuration (which can only be at slot 0) after it. 924 FormatStyle::FormatStyleSet StyleSet; 925 bool LanguageFound = false; 926 for (int i = Styles.size() - 1; i >= 0; --i) { 927 if (Styles[i].Language != FormatStyle::LK_None) 928 StyleSet.Add(Styles[i]); 929 if (Styles[i].Language == Language) 930 LanguageFound = true; 931 } 932 if (!LanguageFound) { 933 if (Styles.empty() || Styles[0].Language != FormatStyle::LK_None) 934 return make_error_code(ParseError::Unsuitable); 935 FormatStyle DefaultStyle = Styles[0]; 936 DefaultStyle.Language = Language; 937 StyleSet.Add(std::move(DefaultStyle)); 938 } 939 *Style = *StyleSet.Get(Language); 940 return make_error_code(ParseError::Success); 941 } 942 943 std::string configurationAsText(const FormatStyle &Style) { 944 std::string Text; 945 llvm::raw_string_ostream Stream(Text); 946 llvm::yaml::Output Output(Stream); 947 // We use the same mapping method for input and output, so we need a non-const 948 // reference here. 949 FormatStyle NonConstStyle = expandPresets(Style); 950 Output << NonConstStyle; 951 return Stream.str(); 952 } 953 954 llvm::Optional<FormatStyle> 955 FormatStyle::FormatStyleSet::Get(FormatStyle::LanguageKind Language) const { 956 if (!Styles) 957 return None; 958 auto It = Styles->find(Language); 959 if (It == Styles->end()) 960 return None; 961 FormatStyle Style = It->second; 962 Style.StyleSet = *this; 963 return Style; 964 } 965 966 void FormatStyle::FormatStyleSet::Add(FormatStyle Style) { 967 assert(Style.Language != LK_None && 968 "Cannot add a style for LK_None to a StyleSet"); 969 assert( 970 !Style.StyleSet.Styles && 971 "Cannot add a style associated with an existing StyleSet to a StyleSet"); 972 if (!Styles) 973 Styles = std::make_shared<MapType>(); 974 (*Styles)[Style.Language] = std::move(Style); 975 } 976 977 void FormatStyle::FormatStyleSet::Clear() { 978 Styles.reset(); 979 } 980 981 llvm::Optional<FormatStyle> 982 FormatStyle::GetLanguageStyle(FormatStyle::LanguageKind Language) const { 983 return StyleSet.Get(Language); 984 } 985 986 namespace { 987 988 class JavaScriptRequoter : public TokenAnalyzer { 989 public: 990 JavaScriptRequoter(const Environment &Env, const FormatStyle &Style) 991 : TokenAnalyzer(Env, Style) {} 992 993 std::pair<tooling::Replacements, unsigned> 994 analyze(TokenAnnotator &Annotator, 995 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, 996 FormatTokenLexer &Tokens) override { 997 AffectedRangeMgr.computeAffectedLines(AnnotatedLines.begin(), 998 AnnotatedLines.end()); 999 tooling::Replacements Result; 1000 requoteJSStringLiteral(AnnotatedLines, Result); 1001 return {Result, 0}; 1002 } 1003 1004 private: 1005 // Replaces double/single-quoted string literal as appropriate, re-escaping 1006 // the contents in the process. 1007 void requoteJSStringLiteral(SmallVectorImpl<AnnotatedLine *> &Lines, 1008 tooling::Replacements &Result) { 1009 for (AnnotatedLine *Line : Lines) { 1010 requoteJSStringLiteral(Line->Children, Result); 1011 if (!Line->Affected) 1012 continue; 1013 for (FormatToken *FormatTok = Line->First; FormatTok; 1014 FormatTok = FormatTok->Next) { 1015 StringRef Input = FormatTok->TokenText; 1016 if (FormatTok->Finalized || !FormatTok->isStringLiteral() || 1017 // NB: testing for not starting with a double quote to avoid 1018 // breaking `template strings`. 1019 (Style.JavaScriptQuotes == FormatStyle::JSQS_Single && 1020 !Input.startswith("\"")) || 1021 (Style.JavaScriptQuotes == FormatStyle::JSQS_Double && 1022 !Input.startswith("\'"))) 1023 continue; 1024 1025 // Change start and end quote. 1026 bool IsSingle = Style.JavaScriptQuotes == FormatStyle::JSQS_Single; 1027 SourceLocation Start = FormatTok->Tok.getLocation(); 1028 auto Replace = [&](SourceLocation Start, unsigned Length, 1029 StringRef ReplacementText) { 1030 auto Err = Result.add(tooling::Replacement( 1031 Env.getSourceManager(), Start, Length, ReplacementText)); 1032 // FIXME: handle error. For now, print error message and skip the 1033 // replacement for release version. 1034 if (Err) { 1035 llvm::errs() << llvm::toString(std::move(Err)) << "\n"; 1036 assert(false); 1037 } 1038 }; 1039 Replace(Start, 1, IsSingle ? "'" : "\""); 1040 Replace(FormatTok->Tok.getEndLoc().getLocWithOffset(-1), 1, 1041 IsSingle ? "'" : "\""); 1042 1043 // Escape internal quotes. 1044 bool Escaped = false; 1045 for (size_t i = 1; i < Input.size() - 1; i++) { 1046 switch (Input[i]) { 1047 case '\\': 1048 if (!Escaped && i + 1 < Input.size() && 1049 ((IsSingle && Input[i + 1] == '"') || 1050 (!IsSingle && Input[i + 1] == '\''))) { 1051 // Remove this \, it's escaping a " or ' that no longer needs 1052 // escaping 1053 Replace(Start.getLocWithOffset(i), 1, ""); 1054 continue; 1055 } 1056 Escaped = !Escaped; 1057 break; 1058 case '\"': 1059 case '\'': 1060 if (!Escaped && IsSingle == (Input[i] == '\'')) { 1061 // Escape the quote. 1062 Replace(Start.getLocWithOffset(i), 0, "\\"); 1063 } 1064 Escaped = false; 1065 break; 1066 default: 1067 Escaped = false; 1068 break; 1069 } 1070 } 1071 } 1072 } 1073 } 1074 }; 1075 1076 class Formatter : public TokenAnalyzer { 1077 public: 1078 Formatter(const Environment &Env, const FormatStyle &Style, 1079 FormattingAttemptStatus *Status) 1080 : TokenAnalyzer(Env, Style), Status(Status) {} 1081 1082 std::pair<tooling::Replacements, unsigned> 1083 analyze(TokenAnnotator &Annotator, 1084 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, 1085 FormatTokenLexer &Tokens) override { 1086 tooling::Replacements Result; 1087 deriveLocalStyle(AnnotatedLines); 1088 AffectedRangeMgr.computeAffectedLines(AnnotatedLines.begin(), 1089 AnnotatedLines.end()); 1090 for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) { 1091 Annotator.calculateFormattingInformation(*AnnotatedLines[i]); 1092 } 1093 Annotator.setCommentLineLevels(AnnotatedLines); 1094 1095 WhitespaceManager Whitespaces( 1096 Env.getSourceManager(), Style, 1097 inputUsesCRLF(Env.getSourceManager().getBufferData(Env.getFileID()))); 1098 ContinuationIndenter Indenter(Style, Tokens.getKeywords(), 1099 Env.getSourceManager(), Whitespaces, Encoding, 1100 BinPackInconclusiveFunctions); 1101 unsigned Penalty = 1102 UnwrappedLineFormatter(&Indenter, &Whitespaces, Style, 1103 Tokens.getKeywords(), Env.getSourceManager(), 1104 Status) 1105 .format(AnnotatedLines, /*DryRun=*/false, 1106 /*AdditionalIndent=*/0, 1107 /*FixBadIndentation=*/false, 1108 /*FirstStartColumn=*/Env.getFirstStartColumn(), 1109 /*NextStartColumn=*/Env.getNextStartColumn(), 1110 /*LastStartColumn=*/Env.getLastStartColumn()); 1111 for (const auto &R : Whitespaces.generateReplacements()) 1112 if (Result.add(R)) 1113 return std::make_pair(Result, 0); 1114 return std::make_pair(Result, Penalty); 1115 } 1116 1117 private: 1118 static bool inputUsesCRLF(StringRef Text) { 1119 return Text.count('\r') * 2 > Text.count('\n'); 1120 } 1121 1122 bool 1123 hasCpp03IncompatibleFormat(const SmallVectorImpl<AnnotatedLine *> &Lines) { 1124 for (const AnnotatedLine *Line : Lines) { 1125 if (hasCpp03IncompatibleFormat(Line->Children)) 1126 return true; 1127 for (FormatToken *Tok = Line->First->Next; Tok; Tok = Tok->Next) { 1128 if (Tok->WhitespaceRange.getBegin() == Tok->WhitespaceRange.getEnd()) { 1129 if (Tok->is(tok::coloncolon) && Tok->Previous->is(TT_TemplateOpener)) 1130 return true; 1131 if (Tok->is(TT_TemplateCloser) && 1132 Tok->Previous->is(TT_TemplateCloser)) 1133 return true; 1134 } 1135 } 1136 } 1137 return false; 1138 } 1139 1140 int countVariableAlignments(const SmallVectorImpl<AnnotatedLine *> &Lines) { 1141 int AlignmentDiff = 0; 1142 for (const AnnotatedLine *Line : Lines) { 1143 AlignmentDiff += countVariableAlignments(Line->Children); 1144 for (FormatToken *Tok = Line->First; Tok && Tok->Next; Tok = Tok->Next) { 1145 if (!Tok->is(TT_PointerOrReference)) 1146 continue; 1147 bool SpaceBefore = 1148 Tok->WhitespaceRange.getBegin() != Tok->WhitespaceRange.getEnd(); 1149 bool SpaceAfter = Tok->Next->WhitespaceRange.getBegin() != 1150 Tok->Next->WhitespaceRange.getEnd(); 1151 if (SpaceBefore && !SpaceAfter) 1152 ++AlignmentDiff; 1153 if (!SpaceBefore && SpaceAfter) 1154 --AlignmentDiff; 1155 } 1156 } 1157 return AlignmentDiff; 1158 } 1159 1160 void 1161 deriveLocalStyle(const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) { 1162 bool HasBinPackedFunction = false; 1163 bool HasOnePerLineFunction = false; 1164 for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) { 1165 if (!AnnotatedLines[i]->First->Next) 1166 continue; 1167 FormatToken *Tok = AnnotatedLines[i]->First->Next; 1168 while (Tok->Next) { 1169 if (Tok->PackingKind == PPK_BinPacked) 1170 HasBinPackedFunction = true; 1171 if (Tok->PackingKind == PPK_OnePerLine) 1172 HasOnePerLineFunction = true; 1173 1174 Tok = Tok->Next; 1175 } 1176 } 1177 if (Style.DerivePointerAlignment) 1178 Style.PointerAlignment = countVariableAlignments(AnnotatedLines) <= 0 1179 ? FormatStyle::PAS_Left 1180 : FormatStyle::PAS_Right; 1181 if (Style.Standard == FormatStyle::LS_Auto) 1182 Style.Standard = hasCpp03IncompatibleFormat(AnnotatedLines) 1183 ? FormatStyle::LS_Cpp11 1184 : FormatStyle::LS_Cpp03; 1185 BinPackInconclusiveFunctions = 1186 HasBinPackedFunction || !HasOnePerLineFunction; 1187 } 1188 1189 bool BinPackInconclusiveFunctions; 1190 FormattingAttemptStatus *Status; 1191 }; 1192 1193 // This class clean up the erroneous/redundant code around the given ranges in 1194 // file. 1195 class Cleaner : public TokenAnalyzer { 1196 public: 1197 Cleaner(const Environment &Env, const FormatStyle &Style) 1198 : TokenAnalyzer(Env, Style), 1199 DeletedTokens(FormatTokenLess(Env.getSourceManager())) {} 1200 1201 // FIXME: eliminate unused parameters. 1202 std::pair<tooling::Replacements, unsigned> 1203 analyze(TokenAnnotator &Annotator, 1204 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, 1205 FormatTokenLexer &Tokens) override { 1206 // FIXME: in the current implementation the granularity of affected range 1207 // is an annotated line. However, this is not sufficient. Furthermore, 1208 // redundant code introduced by replacements does not necessarily 1209 // intercept with ranges of replacements that result in the redundancy. 1210 // To determine if some redundant code is actually introduced by 1211 // replacements(e.g. deletions), we need to come up with a more 1212 // sophisticated way of computing affected ranges. 1213 AffectedRangeMgr.computeAffectedLines(AnnotatedLines.begin(), 1214 AnnotatedLines.end()); 1215 1216 checkEmptyNamespace(AnnotatedLines); 1217 1218 for (auto &Line : AnnotatedLines) { 1219 if (Line->Affected) { 1220 cleanupRight(Line->First, tok::comma, tok::comma); 1221 cleanupRight(Line->First, TT_CtorInitializerColon, tok::comma); 1222 cleanupRight(Line->First, tok::l_paren, tok::comma); 1223 cleanupLeft(Line->First, tok::comma, tok::r_paren); 1224 cleanupLeft(Line->First, TT_CtorInitializerComma, tok::l_brace); 1225 cleanupLeft(Line->First, TT_CtorInitializerColon, tok::l_brace); 1226 cleanupLeft(Line->First, TT_CtorInitializerColon, tok::equal); 1227 } 1228 } 1229 1230 return {generateFixes(), 0}; 1231 } 1232 1233 private: 1234 bool containsOnlyComments(const AnnotatedLine &Line) { 1235 for (FormatToken *Tok = Line.First; Tok != nullptr; Tok = Tok->Next) { 1236 if (Tok->isNot(tok::comment)) 1237 return false; 1238 } 1239 return true; 1240 } 1241 1242 // Iterate through all lines and remove any empty (nested) namespaces. 1243 void checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) { 1244 std::set<unsigned> DeletedLines; 1245 for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) { 1246 auto &Line = *AnnotatedLines[i]; 1247 if (Line.startsWith(tok::kw_namespace) || 1248 Line.startsWith(tok::kw_inline, tok::kw_namespace)) { 1249 checkEmptyNamespace(AnnotatedLines, i, i, DeletedLines); 1250 } 1251 } 1252 1253 for (auto Line : DeletedLines) { 1254 FormatToken *Tok = AnnotatedLines[Line]->First; 1255 while (Tok) { 1256 deleteToken(Tok); 1257 Tok = Tok->Next; 1258 } 1259 } 1260 } 1261 1262 // The function checks if the namespace, which starts from \p CurrentLine, and 1263 // its nested namespaces are empty and delete them if they are empty. It also 1264 // sets \p NewLine to the last line checked. 1265 // Returns true if the current namespace is empty. 1266 bool checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, 1267 unsigned CurrentLine, unsigned &NewLine, 1268 std::set<unsigned> &DeletedLines) { 1269 unsigned InitLine = CurrentLine, End = AnnotatedLines.size(); 1270 if (Style.BraceWrapping.AfterNamespace) { 1271 // If the left brace is in a new line, we should consume it first so that 1272 // it does not make the namespace non-empty. 1273 // FIXME: error handling if there is no left brace. 1274 if (!AnnotatedLines[++CurrentLine]->startsWith(tok::l_brace)) { 1275 NewLine = CurrentLine; 1276 return false; 1277 } 1278 } else if (!AnnotatedLines[CurrentLine]->endsWith(tok::l_brace)) { 1279 return false; 1280 } 1281 while (++CurrentLine < End) { 1282 if (AnnotatedLines[CurrentLine]->startsWith(tok::r_brace)) 1283 break; 1284 1285 if (AnnotatedLines[CurrentLine]->startsWith(tok::kw_namespace) || 1286 AnnotatedLines[CurrentLine]->startsWith(tok::kw_inline, 1287 tok::kw_namespace)) { 1288 if (!checkEmptyNamespace(AnnotatedLines, CurrentLine, NewLine, 1289 DeletedLines)) 1290 return false; 1291 CurrentLine = NewLine; 1292 continue; 1293 } 1294 1295 if (containsOnlyComments(*AnnotatedLines[CurrentLine])) 1296 continue; 1297 1298 // If there is anything other than comments or nested namespaces in the 1299 // current namespace, the namespace cannot be empty. 1300 NewLine = CurrentLine; 1301 return false; 1302 } 1303 1304 NewLine = CurrentLine; 1305 if (CurrentLine >= End) 1306 return false; 1307 1308 // Check if the empty namespace is actually affected by changed ranges. 1309 if (!AffectedRangeMgr.affectsCharSourceRange(CharSourceRange::getCharRange( 1310 AnnotatedLines[InitLine]->First->Tok.getLocation(), 1311 AnnotatedLines[CurrentLine]->Last->Tok.getEndLoc()))) 1312 return false; 1313 1314 for (unsigned i = InitLine; i <= CurrentLine; ++i) { 1315 DeletedLines.insert(i); 1316 } 1317 1318 return true; 1319 } 1320 1321 // Checks pairs {start, start->next},..., {end->previous, end} and deletes one 1322 // of the token in the pair if the left token has \p LK token kind and the 1323 // right token has \p RK token kind. If \p DeleteLeft is true, the left token 1324 // is deleted on match; otherwise, the right token is deleted. 1325 template <typename LeftKind, typename RightKind> 1326 void cleanupPair(FormatToken *Start, LeftKind LK, RightKind RK, 1327 bool DeleteLeft) { 1328 auto NextNotDeleted = [this](const FormatToken &Tok) -> FormatToken * { 1329 for (auto *Res = Tok.Next; Res; Res = Res->Next) 1330 if (!Res->is(tok::comment) && 1331 DeletedTokens.find(Res) == DeletedTokens.end()) 1332 return Res; 1333 return nullptr; 1334 }; 1335 for (auto *Left = Start; Left;) { 1336 auto *Right = NextNotDeleted(*Left); 1337 if (!Right) 1338 break; 1339 if (Left->is(LK) && Right->is(RK)) { 1340 deleteToken(DeleteLeft ? Left : Right); 1341 for (auto *Tok = Left->Next; Tok && Tok != Right; Tok = Tok->Next) 1342 deleteToken(Tok); 1343 // If the right token is deleted, we should keep the left token 1344 // unchanged and pair it with the new right token. 1345 if (!DeleteLeft) 1346 continue; 1347 } 1348 Left = Right; 1349 } 1350 } 1351 1352 template <typename LeftKind, typename RightKind> 1353 void cleanupLeft(FormatToken *Start, LeftKind LK, RightKind RK) { 1354 cleanupPair(Start, LK, RK, /*DeleteLeft=*/true); 1355 } 1356 1357 template <typename LeftKind, typename RightKind> 1358 void cleanupRight(FormatToken *Start, LeftKind LK, RightKind RK) { 1359 cleanupPair(Start, LK, RK, /*DeleteLeft=*/false); 1360 } 1361 1362 // Delete the given token. 1363 inline void deleteToken(FormatToken *Tok) { 1364 if (Tok) 1365 DeletedTokens.insert(Tok); 1366 } 1367 1368 tooling::Replacements generateFixes() { 1369 tooling::Replacements Fixes; 1370 std::vector<FormatToken *> Tokens; 1371 std::copy(DeletedTokens.begin(), DeletedTokens.end(), 1372 std::back_inserter(Tokens)); 1373 1374 // Merge multiple continuous token deletions into one big deletion so that 1375 // the number of replacements can be reduced. This makes computing affected 1376 // ranges more efficient when we run reformat on the changed code. 1377 unsigned Idx = 0; 1378 while (Idx < Tokens.size()) { 1379 unsigned St = Idx, End = Idx; 1380 while ((End + 1) < Tokens.size() && 1381 Tokens[End]->Next == Tokens[End + 1]) { 1382 End++; 1383 } 1384 auto SR = CharSourceRange::getCharRange(Tokens[St]->Tok.getLocation(), 1385 Tokens[End]->Tok.getEndLoc()); 1386 auto Err = 1387 Fixes.add(tooling::Replacement(Env.getSourceManager(), SR, "")); 1388 // FIXME: better error handling. for now just print error message and skip 1389 // for the release version. 1390 if (Err) { 1391 llvm::errs() << llvm::toString(std::move(Err)) << "\n"; 1392 assert(false && "Fixes must not conflict!"); 1393 } 1394 Idx = End + 1; 1395 } 1396 1397 return Fixes; 1398 } 1399 1400 // Class for less-than inequality comparason for the set `RedundantTokens`. 1401 // We store tokens in the order they appear in the translation unit so that 1402 // we do not need to sort them in `generateFixes()`. 1403 struct FormatTokenLess { 1404 FormatTokenLess(const SourceManager &SM) : SM(SM) {} 1405 1406 bool operator()(const FormatToken *LHS, const FormatToken *RHS) const { 1407 return SM.isBeforeInTranslationUnit(LHS->Tok.getLocation(), 1408 RHS->Tok.getLocation()); 1409 } 1410 const SourceManager &SM; 1411 }; 1412 1413 // Tokens to be deleted. 1414 std::set<FormatToken *, FormatTokenLess> DeletedTokens; 1415 }; 1416 1417 class ObjCHeaderStyleGuesser : public TokenAnalyzer { 1418 public: 1419 ObjCHeaderStyleGuesser(const Environment &Env, const FormatStyle &Style) 1420 : TokenAnalyzer(Env, Style), IsObjC(false) {} 1421 1422 std::pair<tooling::Replacements, unsigned> 1423 analyze(TokenAnnotator &Annotator, 1424 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, 1425 FormatTokenLexer &Tokens) override { 1426 assert(Style.Language == FormatStyle::LK_Cpp); 1427 IsObjC = guessIsObjC(AnnotatedLines, Tokens.getKeywords()); 1428 tooling::Replacements Result; 1429 return {Result, 0}; 1430 } 1431 1432 bool isObjC() { return IsObjC; } 1433 1434 private: 1435 static bool guessIsObjC(const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, 1436 const AdditionalKeywords &Keywords) { 1437 // Keep this array sorted, since we are binary searching over it. 1438 static constexpr llvm::StringLiteral FoundationIdentifiers[] = { 1439 "CGFloat", 1440 "NSAffineTransform", 1441 "NSArray", 1442 "NSAttributedString", 1443 "NSCache", 1444 "NSCharacterSet", 1445 "NSCountedSet", 1446 "NSData", 1447 "NSDataDetector", 1448 "NSDecimal", 1449 "NSDecimalNumber", 1450 "NSDictionary", 1451 "NSEdgeInsets", 1452 "NSHashTable", 1453 "NSIndexPath", 1454 "NSIndexSet", 1455 "NSInteger", 1456 "NSLocale", 1457 "NSMapTable", 1458 "NSMutableArray", 1459 "NSMutableAttributedString", 1460 "NSMutableCharacterSet", 1461 "NSMutableData", 1462 "NSMutableDictionary", 1463 "NSMutableIndexSet", 1464 "NSMutableOrderedSet", 1465 "NSMutableSet", 1466 "NSMutableString", 1467 "NSNumber", 1468 "NSNumberFormatter", 1469 "NSOrderedSet", 1470 "NSPoint", 1471 "NSPointerArray", 1472 "NSRange", 1473 "NSRect", 1474 "NSRegularExpression", 1475 "NSSet", 1476 "NSSize", 1477 "NSString", 1478 "NSUInteger", 1479 "NSURL", 1480 "NSURLComponents", 1481 "NSURLQueryItem", 1482 "NSUUID", 1483 }; 1484 1485 for (auto &Line : AnnotatedLines) { 1486 for (FormatToken *FormatTok = Line->First->Next; FormatTok; 1487 FormatTok = FormatTok->Next) { 1488 if ((FormatTok->Previous->is(tok::at) && 1489 (FormatTok->isObjCAtKeyword(tok::objc_interface) || 1490 FormatTok->isObjCAtKeyword(tok::objc_implementation) || 1491 FormatTok->isObjCAtKeyword(tok::objc_protocol) || 1492 FormatTok->isObjCAtKeyword(tok::objc_end) || 1493 FormatTok->isOneOf(tok::numeric_constant, tok::l_square, 1494 tok::l_brace))) || 1495 (FormatTok->Tok.isAnyIdentifier() && 1496 std::binary_search(std::begin(FoundationIdentifiers), 1497 std::end(FoundationIdentifiers), 1498 FormatTok->TokenText)) || 1499 FormatTok->is(TT_ObjCStringLiteral) || 1500 FormatTok->isOneOf(Keywords.kw_NS_ENUM, Keywords.kw_NS_OPTIONS, 1501 TT_ObjCBlockLBrace, TT_ObjCBlockLParen, 1502 TT_ObjCDecl, TT_ObjCForIn, TT_ObjCMethodExpr, 1503 TT_ObjCMethodSpecifier, TT_ObjCProperty)) { 1504 return true; 1505 } 1506 } 1507 } 1508 return false; 1509 } 1510 1511 bool IsObjC; 1512 }; 1513 1514 struct IncludeDirective { 1515 StringRef Filename; 1516 StringRef Text; 1517 unsigned Offset; 1518 int Category; 1519 }; 1520 1521 } // end anonymous namespace 1522 1523 // Determines whether 'Ranges' intersects with ('Start', 'End'). 1524 static bool affectsRange(ArrayRef<tooling::Range> Ranges, unsigned Start, 1525 unsigned End) { 1526 for (auto Range : Ranges) { 1527 if (Range.getOffset() < End && 1528 Range.getOffset() + Range.getLength() > Start) 1529 return true; 1530 } 1531 return false; 1532 } 1533 1534 // Returns a pair (Index, OffsetToEOL) describing the position of the cursor 1535 // before sorting/deduplicating. Index is the index of the include under the 1536 // cursor in the original set of includes. If this include has duplicates, it is 1537 // the index of the first of the duplicates as the others are going to be 1538 // removed. OffsetToEOL describes the cursor's position relative to the end of 1539 // its current line. 1540 // If `Cursor` is not on any #include, `Index` will be UINT_MAX. 1541 static std::pair<unsigned, unsigned> 1542 FindCursorIndex(const SmallVectorImpl<IncludeDirective> &Includes, 1543 const SmallVectorImpl<unsigned> &Indices, unsigned Cursor) { 1544 unsigned CursorIndex = UINT_MAX; 1545 unsigned OffsetToEOL = 0; 1546 for (int i = 0, e = Includes.size(); i != e; ++i) { 1547 unsigned Start = Includes[Indices[i]].Offset; 1548 unsigned End = Start + Includes[Indices[i]].Text.size(); 1549 if (!(Cursor >= Start && Cursor < End)) 1550 continue; 1551 CursorIndex = Indices[i]; 1552 OffsetToEOL = End - Cursor; 1553 // Put the cursor on the only remaining #include among the duplicate 1554 // #includes. 1555 while (--i >= 0 && Includes[CursorIndex].Text == Includes[Indices[i]].Text) 1556 CursorIndex = i; 1557 break; 1558 } 1559 return std::make_pair(CursorIndex, OffsetToEOL); 1560 } 1561 1562 // Sorts and deduplicate a block of includes given by 'Includes' alphabetically 1563 // adding the necessary replacement to 'Replaces'. 'Includes' must be in strict 1564 // source order. 1565 // #include directives with the same text will be deduplicated, and only the 1566 // first #include in the duplicate #includes remains. If the `Cursor` is 1567 // provided and put on a deleted #include, it will be moved to the remaining 1568 // #include in the duplicate #includes. 1569 static void sortCppIncludes(const FormatStyle &Style, 1570 const SmallVectorImpl<IncludeDirective> &Includes, 1571 ArrayRef<tooling::Range> Ranges, StringRef FileName, 1572 tooling::Replacements &Replaces, unsigned *Cursor) { 1573 unsigned IncludesBeginOffset = Includes.front().Offset; 1574 unsigned IncludesEndOffset = 1575 Includes.back().Offset + Includes.back().Text.size(); 1576 unsigned IncludesBlockSize = IncludesEndOffset - IncludesBeginOffset; 1577 if (!affectsRange(Ranges, IncludesBeginOffset, IncludesEndOffset)) 1578 return; 1579 SmallVector<unsigned, 16> Indices; 1580 for (unsigned i = 0, e = Includes.size(); i != e; ++i) 1581 Indices.push_back(i); 1582 std::stable_sort( 1583 Indices.begin(), Indices.end(), [&](unsigned LHSI, unsigned RHSI) { 1584 return std::tie(Includes[LHSI].Category, Includes[LHSI].Filename) < 1585 std::tie(Includes[RHSI].Category, Includes[RHSI].Filename); 1586 }); 1587 // The index of the include on which the cursor will be put after 1588 // sorting/deduplicating. 1589 unsigned CursorIndex; 1590 // The offset from cursor to the end of line. 1591 unsigned CursorToEOLOffset; 1592 if (Cursor) 1593 std::tie(CursorIndex, CursorToEOLOffset) = 1594 FindCursorIndex(Includes, Indices, *Cursor); 1595 1596 // Deduplicate #includes. 1597 Indices.erase(std::unique(Indices.begin(), Indices.end(), 1598 [&](unsigned LHSI, unsigned RHSI) { 1599 return Includes[LHSI].Text == Includes[RHSI].Text; 1600 }), 1601 Indices.end()); 1602 1603 int CurrentCategory = Includes.front().Category; 1604 1605 // If the #includes are out of order, we generate a single replacement fixing 1606 // the entire block. Otherwise, no replacement is generated. 1607 if (Indices.size() == Includes.size() && 1608 std::is_sorted(Indices.begin(), Indices.end()) && 1609 Style.IncludeBlocks == FormatStyle::IBS_Preserve) 1610 return; 1611 1612 std::string result; 1613 for (unsigned Index : Indices) { 1614 if (!result.empty()) { 1615 result += "\n"; 1616 if (Style.IncludeBlocks == FormatStyle::IBS_Regroup && 1617 CurrentCategory != Includes[Index].Category) 1618 result += "\n"; 1619 } 1620 result += Includes[Index].Text; 1621 if (Cursor && CursorIndex == Index) 1622 *Cursor = IncludesBeginOffset + result.size() - CursorToEOLOffset; 1623 CurrentCategory = Includes[Index].Category; 1624 } 1625 1626 auto Err = Replaces.add(tooling::Replacement( 1627 FileName, Includes.front().Offset, IncludesBlockSize, result)); 1628 // FIXME: better error handling. For now, just skip the replacement for the 1629 // release version. 1630 if (Err) { 1631 llvm::errs() << llvm::toString(std::move(Err)) << "\n"; 1632 assert(false); 1633 } 1634 } 1635 1636 namespace { 1637 1638 // This class manages priorities of #include categories and calculates 1639 // priorities for headers. 1640 class IncludeCategoryManager { 1641 public: 1642 IncludeCategoryManager(const FormatStyle &Style, StringRef FileName) 1643 : Style(Style), FileName(FileName) { 1644 FileStem = llvm::sys::path::stem(FileName); 1645 for (const auto &Category : Style.IncludeCategories) 1646 CategoryRegexs.emplace_back(Category.Regex, llvm::Regex::IgnoreCase); 1647 IsMainFile = FileName.endswith(".c") || FileName.endswith(".cc") || 1648 FileName.endswith(".cpp") || FileName.endswith(".c++") || 1649 FileName.endswith(".cxx") || FileName.endswith(".m") || 1650 FileName.endswith(".mm"); 1651 } 1652 1653 // Returns the priority of the category which \p IncludeName belongs to. 1654 // If \p CheckMainHeader is true and \p IncludeName is a main header, returns 1655 // 0. Otherwise, returns the priority of the matching category or INT_MAX. 1656 int getIncludePriority(StringRef IncludeName, bool CheckMainHeader) { 1657 int Ret = INT_MAX; 1658 for (unsigned i = 0, e = CategoryRegexs.size(); i != e; ++i) 1659 if (CategoryRegexs[i].match(IncludeName)) { 1660 Ret = Style.IncludeCategories[i].Priority; 1661 break; 1662 } 1663 if (CheckMainHeader && IsMainFile && Ret > 0 && isMainHeader(IncludeName)) 1664 Ret = 0; 1665 return Ret; 1666 } 1667 1668 private: 1669 bool isMainHeader(StringRef IncludeName) const { 1670 if (!IncludeName.startswith("\"")) 1671 return false; 1672 StringRef HeaderStem = 1673 llvm::sys::path::stem(IncludeName.drop_front(1).drop_back(1)); 1674 if (FileStem.startswith(HeaderStem) || 1675 FileStem.startswith_lower(HeaderStem)) { 1676 llvm::Regex MainIncludeRegex( 1677 (HeaderStem + Style.IncludeIsMainRegex).str(), 1678 llvm::Regex::IgnoreCase); 1679 if (MainIncludeRegex.match(FileStem)) 1680 return true; 1681 } 1682 return false; 1683 } 1684 1685 const FormatStyle &Style; 1686 bool IsMainFile; 1687 StringRef FileName; 1688 StringRef FileStem; 1689 SmallVector<llvm::Regex, 4> CategoryRegexs; 1690 }; 1691 1692 const char IncludeRegexPattern[] = 1693 R"(^[\t\ ]*#[\t\ ]*(import|include)[^"<]*(["<][^">]*[">]))"; 1694 1695 } // anonymous namespace 1696 1697 tooling::Replacements sortCppIncludes(const FormatStyle &Style, StringRef Code, 1698 ArrayRef<tooling::Range> Ranges, 1699 StringRef FileName, 1700 tooling::Replacements &Replaces, 1701 unsigned *Cursor) { 1702 unsigned Prev = 0; 1703 unsigned SearchFrom = 0; 1704 llvm::Regex IncludeRegex(IncludeRegexPattern); 1705 SmallVector<StringRef, 4> Matches; 1706 SmallVector<IncludeDirective, 16> IncludesInBlock; 1707 1708 // In compiled files, consider the first #include to be the main #include of 1709 // the file if it is not a system #include. This ensures that the header 1710 // doesn't have hidden dependencies 1711 // (http://llvm.org/docs/CodingStandards.html#include-style). 1712 // 1713 // FIXME: Do some sanity checking, e.g. edit distance of the base name, to fix 1714 // cases where the first #include is unlikely to be the main header. 1715 IncludeCategoryManager Categories(Style, FileName); 1716 bool FirstIncludeBlock = true; 1717 bool MainIncludeFound = false; 1718 bool FormattingOff = false; 1719 1720 for (;;) { 1721 auto Pos = Code.find('\n', SearchFrom); 1722 StringRef Line = 1723 Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev); 1724 1725 StringRef Trimmed = Line.trim(); 1726 if (Trimmed == "// clang-format off") 1727 FormattingOff = true; 1728 else if (Trimmed == "// clang-format on") 1729 FormattingOff = false; 1730 1731 const bool EmptyLineSkipped = 1732 Trimmed.empty() && (Style.IncludeBlocks == FormatStyle::IBS_Merge || 1733 Style.IncludeBlocks == FormatStyle::IBS_Regroup); 1734 1735 if (!FormattingOff && !Line.endswith("\\")) { 1736 if (IncludeRegex.match(Line, &Matches)) { 1737 StringRef IncludeName = Matches[2]; 1738 int Category = Categories.getIncludePriority( 1739 IncludeName, 1740 /*CheckMainHeader=*/!MainIncludeFound && FirstIncludeBlock); 1741 if (Category == 0) 1742 MainIncludeFound = true; 1743 IncludesInBlock.push_back({IncludeName, Line, Prev, Category}); 1744 } else if (!IncludesInBlock.empty() && !EmptyLineSkipped) { 1745 sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Replaces, 1746 Cursor); 1747 IncludesInBlock.clear(); 1748 FirstIncludeBlock = false; 1749 } 1750 Prev = Pos + 1; 1751 } 1752 if (Pos == StringRef::npos || Pos + 1 == Code.size()) 1753 break; 1754 SearchFrom = Pos + 1; 1755 } 1756 if (!IncludesInBlock.empty()) 1757 sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Replaces, Cursor); 1758 return Replaces; 1759 } 1760 1761 bool isMpegTS(StringRef Code) { 1762 // MPEG transport streams use the ".ts" file extension. clang-format should 1763 // not attempt to format those. MPEG TS' frame format starts with 0x47 every 1764 // 189 bytes - detect that and return. 1765 return Code.size() > 188 && Code[0] == 0x47 && Code[188] == 0x47; 1766 } 1767 1768 bool isLikelyXml(StringRef Code) { return Code.ltrim().startswith("<"); } 1769 1770 tooling::Replacements sortIncludes(const FormatStyle &Style, StringRef Code, 1771 ArrayRef<tooling::Range> Ranges, 1772 StringRef FileName, unsigned *Cursor) { 1773 tooling::Replacements Replaces; 1774 if (!Style.SortIncludes) 1775 return Replaces; 1776 if (isLikelyXml(Code)) 1777 return Replaces; 1778 if (Style.Language == FormatStyle::LanguageKind::LK_JavaScript && 1779 isMpegTS(Code)) 1780 return Replaces; 1781 if (Style.Language == FormatStyle::LanguageKind::LK_JavaScript) 1782 return sortJavaScriptImports(Style, Code, Ranges, FileName); 1783 sortCppIncludes(Style, Code, Ranges, FileName, Replaces, Cursor); 1784 return Replaces; 1785 } 1786 1787 template <typename T> 1788 static llvm::Expected<tooling::Replacements> 1789 processReplacements(T ProcessFunc, StringRef Code, 1790 const tooling::Replacements &Replaces, 1791 const FormatStyle &Style) { 1792 if (Replaces.empty()) 1793 return tooling::Replacements(); 1794 1795 auto NewCode = applyAllReplacements(Code, Replaces); 1796 if (!NewCode) 1797 return NewCode.takeError(); 1798 std::vector<tooling::Range> ChangedRanges = Replaces.getAffectedRanges(); 1799 StringRef FileName = Replaces.begin()->getFilePath(); 1800 1801 tooling::Replacements FormatReplaces = 1802 ProcessFunc(Style, *NewCode, ChangedRanges, FileName); 1803 1804 return Replaces.merge(FormatReplaces); 1805 } 1806 1807 llvm::Expected<tooling::Replacements> 1808 formatReplacements(StringRef Code, const tooling::Replacements &Replaces, 1809 const FormatStyle &Style) { 1810 // We need to use lambda function here since there are two versions of 1811 // `sortIncludes`. 1812 auto SortIncludes = [](const FormatStyle &Style, StringRef Code, 1813 std::vector<tooling::Range> Ranges, 1814 StringRef FileName) -> tooling::Replacements { 1815 return sortIncludes(Style, Code, Ranges, FileName); 1816 }; 1817 auto SortedReplaces = 1818 processReplacements(SortIncludes, Code, Replaces, Style); 1819 if (!SortedReplaces) 1820 return SortedReplaces.takeError(); 1821 1822 // We need to use lambda function here since there are two versions of 1823 // `reformat`. 1824 auto Reformat = [](const FormatStyle &Style, StringRef Code, 1825 std::vector<tooling::Range> Ranges, 1826 StringRef FileName) -> tooling::Replacements { 1827 return reformat(Style, Code, Ranges, FileName); 1828 }; 1829 return processReplacements(Reformat, Code, *SortedReplaces, Style); 1830 } 1831 1832 namespace { 1833 1834 inline bool isHeaderInsertion(const tooling::Replacement &Replace) { 1835 return Replace.getOffset() == UINT_MAX && Replace.getLength() == 0 && 1836 llvm::Regex(IncludeRegexPattern).match(Replace.getReplacementText()); 1837 } 1838 1839 inline bool isHeaderDeletion(const tooling::Replacement &Replace) { 1840 return Replace.getOffset() == UINT_MAX && Replace.getLength() == 1; 1841 } 1842 1843 // Returns the offset after skipping a sequence of tokens, matched by \p 1844 // GetOffsetAfterSequence, from the start of the code. 1845 // \p GetOffsetAfterSequence should be a function that matches a sequence of 1846 // tokens and returns an offset after the sequence. 1847 unsigned getOffsetAfterTokenSequence( 1848 StringRef FileName, StringRef Code, const FormatStyle &Style, 1849 llvm::function_ref<unsigned(const SourceManager &, Lexer &, Token &)> 1850 GetOffsetAfterSequence) { 1851 std::unique_ptr<Environment> Env = 1852 Environment::CreateVirtualEnvironment(Code, FileName, /*Ranges=*/{}); 1853 const SourceManager &SourceMgr = Env->getSourceManager(); 1854 Lexer Lex(Env->getFileID(), SourceMgr.getBuffer(Env->getFileID()), SourceMgr, 1855 getFormattingLangOpts(Style)); 1856 Token Tok; 1857 // Get the first token. 1858 Lex.LexFromRawLexer(Tok); 1859 return GetOffsetAfterSequence(SourceMgr, Lex, Tok); 1860 } 1861 1862 // Check if a sequence of tokens is like "#<Name> <raw_identifier>". If it is, 1863 // \p Tok will be the token after this directive; otherwise, it can be any token 1864 // after the given \p Tok (including \p Tok). 1865 bool checkAndConsumeDirectiveWithName(Lexer &Lex, StringRef Name, Token &Tok) { 1866 bool Matched = Tok.is(tok::hash) && !Lex.LexFromRawLexer(Tok) && 1867 Tok.is(tok::raw_identifier) && 1868 Tok.getRawIdentifier() == Name && !Lex.LexFromRawLexer(Tok) && 1869 Tok.is(tok::raw_identifier); 1870 if (Matched) 1871 Lex.LexFromRawLexer(Tok); 1872 return Matched; 1873 } 1874 1875 void skipComments(Lexer &Lex, Token &Tok) { 1876 while (Tok.is(tok::comment)) 1877 if (Lex.LexFromRawLexer(Tok)) 1878 return; 1879 } 1880 1881 // Returns the offset after header guard directives and any comments 1882 // before/after header guards. If no header guard presents in the code, this 1883 // will returns the offset after skipping all comments from the start of the 1884 // code. 1885 unsigned getOffsetAfterHeaderGuardsAndComments(StringRef FileName, 1886 StringRef Code, 1887 const FormatStyle &Style) { 1888 return getOffsetAfterTokenSequence( 1889 FileName, Code, Style, 1890 [](const SourceManager &SM, Lexer &Lex, Token Tok) { 1891 skipComments(Lex, Tok); 1892 unsigned InitialOffset = SM.getFileOffset(Tok.getLocation()); 1893 if (checkAndConsumeDirectiveWithName(Lex, "ifndef", Tok)) { 1894 skipComments(Lex, Tok); 1895 if (checkAndConsumeDirectiveWithName(Lex, "define", Tok)) 1896 return SM.getFileOffset(Tok.getLocation()); 1897 } 1898 return InitialOffset; 1899 }); 1900 } 1901 1902 // Check if a sequence of tokens is like 1903 // "#include ("header.h" | <header.h>)". 1904 // If it is, \p Tok will be the token after this directive; otherwise, it can be 1905 // any token after the given \p Tok (including \p Tok). 1906 bool checkAndConsumeInclusiveDirective(Lexer &Lex, Token &Tok) { 1907 auto Matched = [&]() { 1908 Lex.LexFromRawLexer(Tok); 1909 return true; 1910 }; 1911 if (Tok.is(tok::hash) && !Lex.LexFromRawLexer(Tok) && 1912 Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "include") { 1913 if (Lex.LexFromRawLexer(Tok)) 1914 return false; 1915 if (Tok.is(tok::string_literal)) 1916 return Matched(); 1917 if (Tok.is(tok::less)) { 1918 while (!Lex.LexFromRawLexer(Tok) && Tok.isNot(tok::greater)) { 1919 } 1920 if (Tok.is(tok::greater)) 1921 return Matched(); 1922 } 1923 } 1924 return false; 1925 } 1926 1927 // Returns the offset of the last #include directive after which a new 1928 // #include can be inserted. This ignores #include's after the #include block(s) 1929 // in the beginning of a file to avoid inserting headers into code sections 1930 // where new #include's should not be added by default. 1931 // These code sections include: 1932 // - raw string literals (containing #include). 1933 // - #if blocks. 1934 // - Special #include's among declarations (e.g. functions). 1935 // 1936 // If no #include after which a new #include can be inserted, this returns the 1937 // offset after skipping all comments from the start of the code. 1938 // Inserting after an #include is not allowed if it comes after code that is not 1939 // #include (e.g. pre-processing directive that is not #include, declarations). 1940 unsigned getMaxHeaderInsertionOffset(StringRef FileName, StringRef Code, 1941 const FormatStyle &Style) { 1942 return getOffsetAfterTokenSequence( 1943 FileName, Code, Style, 1944 [](const SourceManager &SM, Lexer &Lex, Token Tok) { 1945 skipComments(Lex, Tok); 1946 unsigned MaxOffset = SM.getFileOffset(Tok.getLocation()); 1947 while (checkAndConsumeInclusiveDirective(Lex, Tok)) 1948 MaxOffset = SM.getFileOffset(Tok.getLocation()); 1949 return MaxOffset; 1950 }); 1951 } 1952 1953 bool isDeletedHeader(llvm::StringRef HeaderName, 1954 const std::set<llvm::StringRef> &HeadersToDelete) { 1955 return HeadersToDelete.count(HeaderName) || 1956 HeadersToDelete.count(HeaderName.trim("\"<>")); 1957 } 1958 1959 // FIXME: insert empty lines between newly created blocks. 1960 tooling::Replacements 1961 fixCppIncludeInsertions(StringRef Code, const tooling::Replacements &Replaces, 1962 const FormatStyle &Style) { 1963 if (!Style.isCpp()) 1964 return Replaces; 1965 1966 tooling::Replacements HeaderInsertions; 1967 std::set<llvm::StringRef> HeadersToDelete; 1968 tooling::Replacements Result; 1969 for (const auto &R : Replaces) { 1970 if (isHeaderInsertion(R)) { 1971 // Replacements from \p Replaces must be conflict-free already, so we can 1972 // simply consume the error. 1973 llvm::consumeError(HeaderInsertions.add(R)); 1974 } else if (isHeaderDeletion(R)) { 1975 HeadersToDelete.insert(R.getReplacementText()); 1976 } else if (R.getOffset() == UINT_MAX) { 1977 llvm::errs() << "Insertions other than header #include insertion are " 1978 "not supported! " 1979 << R.getReplacementText() << "\n"; 1980 } else { 1981 llvm::consumeError(Result.add(R)); 1982 } 1983 } 1984 if (HeaderInsertions.empty() && HeadersToDelete.empty()) 1985 return Replaces; 1986 1987 llvm::Regex IncludeRegex(IncludeRegexPattern); 1988 llvm::Regex DefineRegex(R"(^[\t\ ]*#[\t\ ]*define[\t\ ]*[^\\]*$)"); 1989 SmallVector<StringRef, 4> Matches; 1990 1991 StringRef FileName = Replaces.begin()->getFilePath(); 1992 IncludeCategoryManager Categories(Style, FileName); 1993 1994 // Record the offset of the end of the last include in each category. 1995 std::map<int, int> CategoryEndOffsets; 1996 // All possible priorities. 1997 // Add 0 for main header and INT_MAX for headers that are not in any category. 1998 std::set<int> Priorities = {0, INT_MAX}; 1999 for (const auto &Category : Style.IncludeCategories) 2000 Priorities.insert(Category.Priority); 2001 int FirstIncludeOffset = -1; 2002 // All new headers should be inserted after this offset. 2003 unsigned MinInsertOffset = 2004 getOffsetAfterHeaderGuardsAndComments(FileName, Code, Style); 2005 StringRef TrimmedCode = Code.drop_front(MinInsertOffset); 2006 // Max insertion offset in the original code. 2007 unsigned MaxInsertOffset = 2008 MinInsertOffset + 2009 getMaxHeaderInsertionOffset(FileName, TrimmedCode, Style); 2010 SmallVector<StringRef, 32> Lines; 2011 TrimmedCode.split(Lines, '\n'); 2012 unsigned Offset = MinInsertOffset; 2013 unsigned NextLineOffset; 2014 std::set<StringRef> ExistingIncludes; 2015 for (auto Line : Lines) { 2016 NextLineOffset = std::min(Code.size(), Offset + Line.size() + 1); 2017 if (IncludeRegex.match(Line, &Matches)) { 2018 // The header name with quotes or angle brackets. 2019 StringRef IncludeName = Matches[2]; 2020 ExistingIncludes.insert(IncludeName); 2021 // Only record the offset of current #include if we can insert after it. 2022 if (Offset <= MaxInsertOffset) { 2023 int Category = Categories.getIncludePriority( 2024 IncludeName, /*CheckMainHeader=*/FirstIncludeOffset < 0); 2025 CategoryEndOffsets[Category] = NextLineOffset; 2026 if (FirstIncludeOffset < 0) 2027 FirstIncludeOffset = Offset; 2028 } 2029 if (isDeletedHeader(IncludeName, HeadersToDelete)) { 2030 // If this is the last line without trailing newline, we need to make 2031 // sure we don't delete across the file boundary. 2032 unsigned Length = std::min(Line.size() + 1, Code.size() - Offset); 2033 llvm::Error Err = 2034 Result.add(tooling::Replacement(FileName, Offset, Length, "")); 2035 if (Err) { 2036 // Ignore the deletion on conflict. 2037 llvm::errs() << "Failed to add header deletion replacement for " 2038 << IncludeName << ": " << llvm::toString(std::move(Err)) 2039 << "\n"; 2040 } 2041 } 2042 } 2043 Offset = NextLineOffset; 2044 } 2045 2046 // Populate CategoryEndOfssets: 2047 // - Ensure that CategoryEndOffset[Highest] is always populated. 2048 // - If CategoryEndOffset[Priority] isn't set, use the next higher value that 2049 // is set, up to CategoryEndOffset[Highest]. 2050 auto Highest = Priorities.begin(); 2051 if (CategoryEndOffsets.find(*Highest) == CategoryEndOffsets.end()) { 2052 if (FirstIncludeOffset >= 0) 2053 CategoryEndOffsets[*Highest] = FirstIncludeOffset; 2054 else 2055 CategoryEndOffsets[*Highest] = MinInsertOffset; 2056 } 2057 // By this point, CategoryEndOffset[Highest] is always set appropriately: 2058 // - to an appropriate location before/after existing #includes, or 2059 // - to right after the header guard, or 2060 // - to the beginning of the file. 2061 for (auto I = ++Priorities.begin(), E = Priorities.end(); I != E; ++I) 2062 if (CategoryEndOffsets.find(*I) == CategoryEndOffsets.end()) 2063 CategoryEndOffsets[*I] = CategoryEndOffsets[*std::prev(I)]; 2064 2065 bool NeedNewLineAtEnd = !Code.empty() && Code.back() != '\n'; 2066 for (const auto &R : HeaderInsertions) { 2067 auto IncludeDirective = R.getReplacementText(); 2068 bool Matched = IncludeRegex.match(IncludeDirective, &Matches); 2069 assert(Matched && "Header insertion replacement must have replacement text " 2070 "'#include ...'"); 2071 (void)Matched; 2072 auto IncludeName = Matches[2]; 2073 if (ExistingIncludes.find(IncludeName) != ExistingIncludes.end()) { 2074 DEBUG(llvm::dbgs() << "Skip adding existing include : " << IncludeName 2075 << "\n"); 2076 continue; 2077 } 2078 int Category = 2079 Categories.getIncludePriority(IncludeName, /*CheckMainHeader=*/true); 2080 Offset = CategoryEndOffsets[Category]; 2081 std::string NewInclude = !IncludeDirective.endswith("\n") 2082 ? (IncludeDirective + "\n").str() 2083 : IncludeDirective.str(); 2084 // When inserting headers at end of the code, also append '\n' to the code 2085 // if it does not end with '\n'. 2086 if (NeedNewLineAtEnd && Offset == Code.size()) { 2087 NewInclude = "\n" + NewInclude; 2088 NeedNewLineAtEnd = false; 2089 } 2090 auto NewReplace = tooling::Replacement(FileName, Offset, 0, NewInclude); 2091 auto Err = Result.add(NewReplace); 2092 if (Err) { 2093 llvm::consumeError(std::move(Err)); 2094 unsigned NewOffset = Result.getShiftedCodePosition(Offset); 2095 NewReplace = tooling::Replacement(FileName, NewOffset, 0, NewInclude); 2096 Result = Result.merge(tooling::Replacements(NewReplace)); 2097 } 2098 } 2099 return Result; 2100 } 2101 2102 } // anonymous namespace 2103 2104 llvm::Expected<tooling::Replacements> 2105 cleanupAroundReplacements(StringRef Code, const tooling::Replacements &Replaces, 2106 const FormatStyle &Style) { 2107 // We need to use lambda function here since there are two versions of 2108 // `cleanup`. 2109 auto Cleanup = [](const FormatStyle &Style, StringRef Code, 2110 std::vector<tooling::Range> Ranges, 2111 StringRef FileName) -> tooling::Replacements { 2112 return cleanup(Style, Code, Ranges, FileName); 2113 }; 2114 // Make header insertion replacements insert new headers into correct blocks. 2115 tooling::Replacements NewReplaces = 2116 fixCppIncludeInsertions(Code, Replaces, Style); 2117 return processReplacements(Cleanup, Code, NewReplaces, Style); 2118 } 2119 2120 namespace internal { 2121 std::pair<tooling::Replacements, unsigned> 2122 reformat(const FormatStyle &Style, StringRef Code, 2123 ArrayRef<tooling::Range> Ranges, unsigned FirstStartColumn, 2124 unsigned NextStartColumn, unsigned LastStartColumn, StringRef FileName, 2125 FormattingAttemptStatus *Status) { 2126 FormatStyle Expanded = expandPresets(Style); 2127 if (Expanded.DisableFormat) 2128 return {tooling::Replacements(), 0}; 2129 if (isLikelyXml(Code)) 2130 return {tooling::Replacements(), 0}; 2131 if (Expanded.Language == FormatStyle::LK_JavaScript && isMpegTS(Code)) 2132 return {tooling::Replacements(), 0}; 2133 2134 typedef std::function<std::pair<tooling::Replacements, unsigned>( 2135 const Environment &)> 2136 AnalyzerPass; 2137 SmallVector<AnalyzerPass, 4> Passes; 2138 2139 if (Style.Language == FormatStyle::LK_Cpp) { 2140 if (Style.FixNamespaceComments) 2141 Passes.emplace_back([&](const Environment &Env) { 2142 return NamespaceEndCommentsFixer(Env, Expanded).process(); 2143 }); 2144 2145 if (Style.SortUsingDeclarations) 2146 Passes.emplace_back([&](const Environment &Env) { 2147 return UsingDeclarationsSorter(Env, Expanded).process(); 2148 }); 2149 } 2150 2151 if (Style.Language == FormatStyle::LK_JavaScript && 2152 Style.JavaScriptQuotes != FormatStyle::JSQS_Leave) 2153 Passes.emplace_back([&](const Environment &Env) { 2154 return JavaScriptRequoter(Env, Expanded).process(); 2155 }); 2156 2157 Passes.emplace_back([&](const Environment &Env) { 2158 return Formatter(Env, Expanded, Status).process(); 2159 }); 2160 2161 std::unique_ptr<Environment> Env = Environment::CreateVirtualEnvironment( 2162 Code, FileName, Ranges, FirstStartColumn, NextStartColumn, 2163 LastStartColumn); 2164 llvm::Optional<std::string> CurrentCode = None; 2165 tooling::Replacements Fixes; 2166 unsigned Penalty = 0; 2167 for (size_t I = 0, E = Passes.size(); I < E; ++I) { 2168 std::pair<tooling::Replacements, unsigned> PassFixes = Passes[I](*Env); 2169 auto NewCode = applyAllReplacements( 2170 CurrentCode ? StringRef(*CurrentCode) : Code, PassFixes.first); 2171 if (NewCode) { 2172 Fixes = Fixes.merge(PassFixes.first); 2173 Penalty += PassFixes.second; 2174 if (I + 1 < E) { 2175 CurrentCode = std::move(*NewCode); 2176 Env = Environment::CreateVirtualEnvironment( 2177 *CurrentCode, FileName, 2178 tooling::calculateRangesAfterReplacements(Fixes, Ranges), 2179 FirstStartColumn, NextStartColumn, LastStartColumn); 2180 } 2181 } 2182 } 2183 2184 return {Fixes, Penalty}; 2185 } 2186 } // namespace internal 2187 2188 tooling::Replacements reformat(const FormatStyle &Style, StringRef Code, 2189 ArrayRef<tooling::Range> Ranges, 2190 StringRef FileName, 2191 FormattingAttemptStatus *Status) { 2192 return internal::reformat(Style, Code, Ranges, 2193 /*FirstStartColumn=*/0, 2194 /*NextStartColumn=*/0, 2195 /*LastStartColumn=*/0, FileName, Status) 2196 .first; 2197 } 2198 2199 tooling::Replacements cleanup(const FormatStyle &Style, StringRef Code, 2200 ArrayRef<tooling::Range> Ranges, 2201 StringRef FileName) { 2202 // cleanups only apply to C++ (they mostly concern ctor commas etc.) 2203 if (Style.Language != FormatStyle::LK_Cpp) 2204 return tooling::Replacements(); 2205 std::unique_ptr<Environment> Env = 2206 Environment::CreateVirtualEnvironment(Code, FileName, Ranges); 2207 Cleaner Clean(*Env, Style); 2208 return Clean.process().first; 2209 } 2210 2211 tooling::Replacements reformat(const FormatStyle &Style, StringRef Code, 2212 ArrayRef<tooling::Range> Ranges, 2213 StringRef FileName, bool *IncompleteFormat) { 2214 FormattingAttemptStatus Status; 2215 auto Result = reformat(Style, Code, Ranges, FileName, &Status); 2216 if (!Status.FormatComplete) 2217 *IncompleteFormat = true; 2218 return Result; 2219 } 2220 2221 tooling::Replacements fixNamespaceEndComments(const FormatStyle &Style, 2222 StringRef Code, 2223 ArrayRef<tooling::Range> Ranges, 2224 StringRef FileName) { 2225 std::unique_ptr<Environment> Env = 2226 Environment::CreateVirtualEnvironment(Code, FileName, Ranges); 2227 NamespaceEndCommentsFixer Fix(*Env, Style); 2228 return Fix.process().first; 2229 } 2230 2231 tooling::Replacements sortUsingDeclarations(const FormatStyle &Style, 2232 StringRef Code, 2233 ArrayRef<tooling::Range> Ranges, 2234 StringRef FileName) { 2235 std::unique_ptr<Environment> Env = 2236 Environment::CreateVirtualEnvironment(Code, FileName, Ranges); 2237 UsingDeclarationsSorter Sorter(*Env, Style); 2238 return Sorter.process().first; 2239 } 2240 2241 LangOptions getFormattingLangOpts(const FormatStyle &Style) { 2242 LangOptions LangOpts; 2243 LangOpts.CPlusPlus = 1; 2244 LangOpts.CPlusPlus11 = Style.Standard == FormatStyle::LS_Cpp03 ? 0 : 1; 2245 LangOpts.CPlusPlus14 = Style.Standard == FormatStyle::LS_Cpp03 ? 0 : 1; 2246 LangOpts.CPlusPlus17 = Style.Standard == FormatStyle::LS_Cpp03 ? 0 : 1; 2247 LangOpts.CPlusPlus2a = Style.Standard == FormatStyle::LS_Cpp03 ? 0 : 1; 2248 LangOpts.LineComment = 1; 2249 bool AlternativeOperators = Style.isCpp(); 2250 LangOpts.CXXOperatorNames = AlternativeOperators ? 1 : 0; 2251 LangOpts.Bool = 1; 2252 LangOpts.ObjC1 = 1; 2253 LangOpts.ObjC2 = 1; 2254 LangOpts.MicrosoftExt = 1; // To get kw___try, kw___finally. 2255 LangOpts.DeclSpecKeyword = 1; // To get __declspec. 2256 return LangOpts; 2257 } 2258 2259 const char *StyleOptionHelpDescription = 2260 "Coding style, currently supports:\n" 2261 " LLVM, Google, Chromium, Mozilla, WebKit.\n" 2262 "Use -style=file to load style configuration from\n" 2263 ".clang-format file located in one of the parent\n" 2264 "directories of the source file (or current\n" 2265 "directory for stdin).\n" 2266 "Use -style=\"{key: value, ...}\" to set specific\n" 2267 "parameters, e.g.:\n" 2268 " -style=\"{BasedOnStyle: llvm, IndentWidth: 8}\""; 2269 2270 static FormatStyle::LanguageKind getLanguageByFileName(StringRef FileName) { 2271 if (FileName.endswith(".java")) 2272 return FormatStyle::LK_Java; 2273 if (FileName.endswith_lower(".js") || FileName.endswith_lower(".ts")) 2274 return FormatStyle::LK_JavaScript; // JavaScript or TypeScript. 2275 if (FileName.endswith(".m") || FileName.endswith(".mm")) 2276 return FormatStyle::LK_ObjC; 2277 if (FileName.endswith_lower(".proto") || 2278 FileName.endswith_lower(".protodevel")) 2279 return FormatStyle::LK_Proto; 2280 if (FileName.endswith_lower(".textpb") || 2281 FileName.endswith_lower(".pb.txt") || 2282 FileName.endswith_lower(".textproto") || 2283 FileName.endswith_lower(".asciipb")) 2284 return FormatStyle::LK_TextProto; 2285 if (FileName.endswith_lower(".td")) 2286 return FormatStyle::LK_TableGen; 2287 return FormatStyle::LK_Cpp; 2288 } 2289 2290 llvm::Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName, 2291 StringRef FallbackStyleName, 2292 StringRef Code, vfs::FileSystem *FS) { 2293 if (!FS) { 2294 FS = vfs::getRealFileSystem().get(); 2295 } 2296 FormatStyle Style = getLLVMStyle(); 2297 Style.Language = getLanguageByFileName(FileName); 2298 2299 if (Style.Language == FormatStyle::LK_Cpp && FileName.endswith(".h")) { 2300 std::unique_ptr<Environment> Env = 2301 Environment::CreateVirtualEnvironment(Code, FileName, /*Ranges=*/{}); 2302 ObjCHeaderStyleGuesser Guesser(*Env, Style); 2303 Guesser.process(); 2304 if (Guesser.isObjC()) { 2305 Style.Language = FormatStyle::LK_ObjC; 2306 } 2307 } 2308 2309 FormatStyle FallbackStyle = getNoStyle(); 2310 if (!getPredefinedStyle(FallbackStyleName, Style.Language, &FallbackStyle)) 2311 return make_string_error("Invalid fallback style \"" + FallbackStyleName); 2312 2313 if (StyleName.startswith("{")) { 2314 // Parse YAML/JSON style from the command line. 2315 if (std::error_code ec = parseConfiguration(StyleName, &Style)) 2316 return make_string_error("Error parsing -style: " + ec.message()); 2317 return Style; 2318 } 2319 2320 if (!StyleName.equals_lower("file")) { 2321 if (!getPredefinedStyle(StyleName, Style.Language, &Style)) 2322 return make_string_error("Invalid value for -style"); 2323 return Style; 2324 } 2325 2326 // Look for .clang-format/_clang-format file in the file's parent directories. 2327 SmallString<128> UnsuitableConfigFiles; 2328 SmallString<128> Path(FileName); 2329 if (std::error_code EC = FS->makeAbsolute(Path)) 2330 return make_string_error(EC.message()); 2331 2332 for (StringRef Directory = Path; !Directory.empty(); 2333 Directory = llvm::sys::path::parent_path(Directory)) { 2334 2335 auto Status = FS->status(Directory); 2336 if (!Status || 2337 Status->getType() != llvm::sys::fs::file_type::directory_file) { 2338 continue; 2339 } 2340 2341 SmallString<128> ConfigFile(Directory); 2342 2343 llvm::sys::path::append(ConfigFile, ".clang-format"); 2344 DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n"); 2345 2346 Status = FS->status(ConfigFile.str()); 2347 bool FoundConfigFile = 2348 Status && (Status->getType() == llvm::sys::fs::file_type::regular_file); 2349 if (!FoundConfigFile) { 2350 // Try _clang-format too, since dotfiles are not commonly used on Windows. 2351 ConfigFile = Directory; 2352 llvm::sys::path::append(ConfigFile, "_clang-format"); 2353 DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n"); 2354 Status = FS->status(ConfigFile.str()); 2355 FoundConfigFile = Status && (Status->getType() == 2356 llvm::sys::fs::file_type::regular_file); 2357 } 2358 2359 if (FoundConfigFile) { 2360 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text = 2361 FS->getBufferForFile(ConfigFile.str()); 2362 if (std::error_code EC = Text.getError()) 2363 return make_string_error(EC.message()); 2364 if (std::error_code ec = 2365 parseConfiguration(Text.get()->getBuffer(), &Style)) { 2366 if (ec == ParseError::Unsuitable) { 2367 if (!UnsuitableConfigFiles.empty()) 2368 UnsuitableConfigFiles.append(", "); 2369 UnsuitableConfigFiles.append(ConfigFile); 2370 continue; 2371 } 2372 return make_string_error("Error reading " + ConfigFile + ": " + 2373 ec.message()); 2374 } 2375 DEBUG(llvm::dbgs() << "Using configuration file " << ConfigFile << "\n"); 2376 return Style; 2377 } 2378 } 2379 if (!UnsuitableConfigFiles.empty()) 2380 return make_string_error("Configuration file(s) do(es) not support " + 2381 getLanguageName(Style.Language) + ": " + 2382 UnsuitableConfigFiles); 2383 return FallbackStyle; 2384 } 2385 2386 } // namespace format 2387 } // namespace clang 2388