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