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