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