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