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