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 auto LineContainsObjCCode = [&Keywords](const AnnotatedLine &Line) { 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 } 1539 return false; 1540 }; 1541 for (auto Line : AnnotatedLines) { 1542 if (LineContainsObjCCode(*Line)) 1543 return true; 1544 for (auto ChildLine : Line->Children) { 1545 if (LineContainsObjCCode(*ChildLine)) 1546 return true; 1547 } 1548 } 1549 return false; 1550 } 1551 1552 bool IsObjC; 1553 }; 1554 1555 struct IncludeDirective { 1556 StringRef Filename; 1557 StringRef Text; 1558 unsigned Offset; 1559 int Category; 1560 }; 1561 1562 } // end anonymous namespace 1563 1564 // Determines whether 'Ranges' intersects with ('Start', 'End'). 1565 static bool affectsRange(ArrayRef<tooling::Range> Ranges, unsigned Start, 1566 unsigned End) { 1567 for (auto Range : Ranges) { 1568 if (Range.getOffset() < End && 1569 Range.getOffset() + Range.getLength() > Start) 1570 return true; 1571 } 1572 return false; 1573 } 1574 1575 // Returns a pair (Index, OffsetToEOL) describing the position of the cursor 1576 // before sorting/deduplicating. Index is the index of the include under the 1577 // cursor in the original set of includes. If this include has duplicates, it is 1578 // the index of the first of the duplicates as the others are going to be 1579 // removed. OffsetToEOL describes the cursor's position relative to the end of 1580 // its current line. 1581 // If `Cursor` is not on any #include, `Index` will be UINT_MAX. 1582 static std::pair<unsigned, unsigned> 1583 FindCursorIndex(const SmallVectorImpl<IncludeDirective> &Includes, 1584 const SmallVectorImpl<unsigned> &Indices, unsigned Cursor) { 1585 unsigned CursorIndex = UINT_MAX; 1586 unsigned OffsetToEOL = 0; 1587 for (int i = 0, e = Includes.size(); i != e; ++i) { 1588 unsigned Start = Includes[Indices[i]].Offset; 1589 unsigned End = Start + Includes[Indices[i]].Text.size(); 1590 if (!(Cursor >= Start && Cursor < End)) 1591 continue; 1592 CursorIndex = Indices[i]; 1593 OffsetToEOL = End - Cursor; 1594 // Put the cursor on the only remaining #include among the duplicate 1595 // #includes. 1596 while (--i >= 0 && Includes[CursorIndex].Text == Includes[Indices[i]].Text) 1597 CursorIndex = i; 1598 break; 1599 } 1600 return std::make_pair(CursorIndex, OffsetToEOL); 1601 } 1602 1603 // Sorts and deduplicate a block of includes given by 'Includes' alphabetically 1604 // adding the necessary replacement to 'Replaces'. 'Includes' must be in strict 1605 // source order. 1606 // #include directives with the same text will be deduplicated, and only the 1607 // first #include in the duplicate #includes remains. If the `Cursor` is 1608 // provided and put on a deleted #include, it will be moved to the remaining 1609 // #include in the duplicate #includes. 1610 static void sortCppIncludes(const FormatStyle &Style, 1611 const SmallVectorImpl<IncludeDirective> &Includes, 1612 ArrayRef<tooling::Range> Ranges, StringRef FileName, 1613 tooling::Replacements &Replaces, unsigned *Cursor) { 1614 unsigned IncludesBeginOffset = Includes.front().Offset; 1615 unsigned IncludesEndOffset = 1616 Includes.back().Offset + Includes.back().Text.size(); 1617 unsigned IncludesBlockSize = IncludesEndOffset - IncludesBeginOffset; 1618 if (!affectsRange(Ranges, IncludesBeginOffset, IncludesEndOffset)) 1619 return; 1620 SmallVector<unsigned, 16> Indices; 1621 for (unsigned i = 0, e = Includes.size(); i != e; ++i) 1622 Indices.push_back(i); 1623 std::stable_sort( 1624 Indices.begin(), Indices.end(), [&](unsigned LHSI, unsigned RHSI) { 1625 return std::tie(Includes[LHSI].Category, Includes[LHSI].Filename) < 1626 std::tie(Includes[RHSI].Category, Includes[RHSI].Filename); 1627 }); 1628 // The index of the include on which the cursor will be put after 1629 // sorting/deduplicating. 1630 unsigned CursorIndex; 1631 // The offset from cursor to the end of line. 1632 unsigned CursorToEOLOffset; 1633 if (Cursor) 1634 std::tie(CursorIndex, CursorToEOLOffset) = 1635 FindCursorIndex(Includes, Indices, *Cursor); 1636 1637 // Deduplicate #includes. 1638 Indices.erase(std::unique(Indices.begin(), Indices.end(), 1639 [&](unsigned LHSI, unsigned RHSI) { 1640 return Includes[LHSI].Text == Includes[RHSI].Text; 1641 }), 1642 Indices.end()); 1643 1644 int CurrentCategory = Includes.front().Category; 1645 1646 // If the #includes are out of order, we generate a single replacement fixing 1647 // the entire block. Otherwise, no replacement is generated. 1648 if (Indices.size() == Includes.size() && 1649 std::is_sorted(Indices.begin(), Indices.end()) && 1650 Style.IncludeBlocks == FormatStyle::IBS_Preserve) 1651 return; 1652 1653 std::string result; 1654 for (unsigned Index : Indices) { 1655 if (!result.empty()) { 1656 result += "\n"; 1657 if (Style.IncludeBlocks == FormatStyle::IBS_Regroup && 1658 CurrentCategory != Includes[Index].Category) 1659 result += "\n"; 1660 } 1661 result += Includes[Index].Text; 1662 if (Cursor && CursorIndex == Index) 1663 *Cursor = IncludesBeginOffset + result.size() - CursorToEOLOffset; 1664 CurrentCategory = Includes[Index].Category; 1665 } 1666 1667 auto Err = Replaces.add(tooling::Replacement( 1668 FileName, Includes.front().Offset, IncludesBlockSize, result)); 1669 // FIXME: better error handling. For now, just skip the replacement for the 1670 // release version. 1671 if (Err) { 1672 llvm::errs() << llvm::toString(std::move(Err)) << "\n"; 1673 assert(false); 1674 } 1675 } 1676 1677 namespace { 1678 1679 // This class manages priorities of #include categories and calculates 1680 // priorities for headers. 1681 class IncludeCategoryManager { 1682 public: 1683 IncludeCategoryManager(const FormatStyle &Style, StringRef FileName) 1684 : Style(Style), FileName(FileName) { 1685 FileStem = llvm::sys::path::stem(FileName); 1686 for (const auto &Category : Style.IncludeCategories) 1687 CategoryRegexs.emplace_back(Category.Regex, llvm::Regex::IgnoreCase); 1688 IsMainFile = FileName.endswith(".c") || FileName.endswith(".cc") || 1689 FileName.endswith(".cpp") || FileName.endswith(".c++") || 1690 FileName.endswith(".cxx") || FileName.endswith(".m") || 1691 FileName.endswith(".mm"); 1692 } 1693 1694 // Returns the priority of the category which \p IncludeName belongs to. 1695 // If \p CheckMainHeader is true and \p IncludeName is a main header, returns 1696 // 0. Otherwise, returns the priority of the matching category or INT_MAX. 1697 int getIncludePriority(StringRef IncludeName, bool CheckMainHeader) { 1698 int Ret = INT_MAX; 1699 for (unsigned i = 0, e = CategoryRegexs.size(); i != e; ++i) 1700 if (CategoryRegexs[i].match(IncludeName)) { 1701 Ret = Style.IncludeCategories[i].Priority; 1702 break; 1703 } 1704 if (CheckMainHeader && IsMainFile && Ret > 0 && isMainHeader(IncludeName)) 1705 Ret = 0; 1706 return Ret; 1707 } 1708 1709 private: 1710 bool isMainHeader(StringRef IncludeName) const { 1711 if (!IncludeName.startswith("\"")) 1712 return false; 1713 StringRef HeaderStem = 1714 llvm::sys::path::stem(IncludeName.drop_front(1).drop_back(1)); 1715 if (FileStem.startswith(HeaderStem) || 1716 FileStem.startswith_lower(HeaderStem)) { 1717 llvm::Regex MainIncludeRegex( 1718 (HeaderStem + Style.IncludeIsMainRegex).str(), 1719 llvm::Regex::IgnoreCase); 1720 if (MainIncludeRegex.match(FileStem)) 1721 return true; 1722 } 1723 return false; 1724 } 1725 1726 const FormatStyle &Style; 1727 bool IsMainFile; 1728 StringRef FileName; 1729 StringRef FileStem; 1730 SmallVector<llvm::Regex, 4> CategoryRegexs; 1731 }; 1732 1733 const char IncludeRegexPattern[] = 1734 R"(^[\t\ ]*#[\t\ ]*(import|include)[^"<]*(["<][^">]*[">]))"; 1735 1736 } // anonymous namespace 1737 1738 tooling::Replacements sortCppIncludes(const FormatStyle &Style, StringRef Code, 1739 ArrayRef<tooling::Range> Ranges, 1740 StringRef FileName, 1741 tooling::Replacements &Replaces, 1742 unsigned *Cursor) { 1743 unsigned Prev = 0; 1744 unsigned SearchFrom = 0; 1745 llvm::Regex IncludeRegex(IncludeRegexPattern); 1746 SmallVector<StringRef, 4> Matches; 1747 SmallVector<IncludeDirective, 16> IncludesInBlock; 1748 1749 // In compiled files, consider the first #include to be the main #include of 1750 // the file if it is not a system #include. This ensures that the header 1751 // doesn't have hidden dependencies 1752 // (http://llvm.org/docs/CodingStandards.html#include-style). 1753 // 1754 // FIXME: Do some sanity checking, e.g. edit distance of the base name, to fix 1755 // cases where the first #include is unlikely to be the main header. 1756 IncludeCategoryManager Categories(Style, FileName); 1757 bool FirstIncludeBlock = true; 1758 bool MainIncludeFound = false; 1759 bool FormattingOff = false; 1760 1761 for (;;) { 1762 auto Pos = Code.find('\n', SearchFrom); 1763 StringRef Line = 1764 Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev); 1765 1766 StringRef Trimmed = Line.trim(); 1767 if (Trimmed == "// clang-format off") 1768 FormattingOff = true; 1769 else if (Trimmed == "// clang-format on") 1770 FormattingOff = false; 1771 1772 const bool EmptyLineSkipped = 1773 Trimmed.empty() && (Style.IncludeBlocks == FormatStyle::IBS_Merge || 1774 Style.IncludeBlocks == FormatStyle::IBS_Regroup); 1775 1776 if (!FormattingOff && !Line.endswith("\\")) { 1777 if (IncludeRegex.match(Line, &Matches)) { 1778 StringRef IncludeName = Matches[2]; 1779 int Category = Categories.getIncludePriority( 1780 IncludeName, 1781 /*CheckMainHeader=*/!MainIncludeFound && FirstIncludeBlock); 1782 if (Category == 0) 1783 MainIncludeFound = true; 1784 IncludesInBlock.push_back({IncludeName, Line, Prev, Category}); 1785 } else if (!IncludesInBlock.empty() && !EmptyLineSkipped) { 1786 sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Replaces, 1787 Cursor); 1788 IncludesInBlock.clear(); 1789 FirstIncludeBlock = false; 1790 } 1791 Prev = Pos + 1; 1792 } 1793 if (Pos == StringRef::npos || Pos + 1 == Code.size()) 1794 break; 1795 SearchFrom = Pos + 1; 1796 } 1797 if (!IncludesInBlock.empty()) 1798 sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Replaces, Cursor); 1799 return Replaces; 1800 } 1801 1802 bool isMpegTS(StringRef Code) { 1803 // MPEG transport streams use the ".ts" file extension. clang-format should 1804 // not attempt to format those. MPEG TS' frame format starts with 0x47 every 1805 // 189 bytes - detect that and return. 1806 return Code.size() > 188 && Code[0] == 0x47 && Code[188] == 0x47; 1807 } 1808 1809 bool isLikelyXml(StringRef Code) { return Code.ltrim().startswith("<"); } 1810 1811 tooling::Replacements sortIncludes(const FormatStyle &Style, StringRef Code, 1812 ArrayRef<tooling::Range> Ranges, 1813 StringRef FileName, unsigned *Cursor) { 1814 tooling::Replacements Replaces; 1815 if (!Style.SortIncludes) 1816 return Replaces; 1817 if (isLikelyXml(Code)) 1818 return Replaces; 1819 if (Style.Language == FormatStyle::LanguageKind::LK_JavaScript && 1820 isMpegTS(Code)) 1821 return Replaces; 1822 if (Style.Language == FormatStyle::LanguageKind::LK_JavaScript) 1823 return sortJavaScriptImports(Style, Code, Ranges, FileName); 1824 sortCppIncludes(Style, Code, Ranges, FileName, Replaces, Cursor); 1825 return Replaces; 1826 } 1827 1828 template <typename T> 1829 static llvm::Expected<tooling::Replacements> 1830 processReplacements(T ProcessFunc, StringRef Code, 1831 const tooling::Replacements &Replaces, 1832 const FormatStyle &Style) { 1833 if (Replaces.empty()) 1834 return tooling::Replacements(); 1835 1836 auto NewCode = applyAllReplacements(Code, Replaces); 1837 if (!NewCode) 1838 return NewCode.takeError(); 1839 std::vector<tooling::Range> ChangedRanges = Replaces.getAffectedRanges(); 1840 StringRef FileName = Replaces.begin()->getFilePath(); 1841 1842 tooling::Replacements FormatReplaces = 1843 ProcessFunc(Style, *NewCode, ChangedRanges, FileName); 1844 1845 return Replaces.merge(FormatReplaces); 1846 } 1847 1848 llvm::Expected<tooling::Replacements> 1849 formatReplacements(StringRef Code, const tooling::Replacements &Replaces, 1850 const FormatStyle &Style) { 1851 // We need to use lambda function here since there are two versions of 1852 // `sortIncludes`. 1853 auto SortIncludes = [](const FormatStyle &Style, StringRef Code, 1854 std::vector<tooling::Range> Ranges, 1855 StringRef FileName) -> tooling::Replacements { 1856 return sortIncludes(Style, Code, Ranges, FileName); 1857 }; 1858 auto SortedReplaces = 1859 processReplacements(SortIncludes, Code, Replaces, Style); 1860 if (!SortedReplaces) 1861 return SortedReplaces.takeError(); 1862 1863 // We need to use lambda function here since there are two versions of 1864 // `reformat`. 1865 auto Reformat = [](const FormatStyle &Style, StringRef Code, 1866 std::vector<tooling::Range> Ranges, 1867 StringRef FileName) -> tooling::Replacements { 1868 return reformat(Style, Code, Ranges, FileName); 1869 }; 1870 return processReplacements(Reformat, Code, *SortedReplaces, Style); 1871 } 1872 1873 namespace { 1874 1875 inline bool isHeaderInsertion(const tooling::Replacement &Replace) { 1876 return Replace.getOffset() == UINT_MAX && Replace.getLength() == 0 && 1877 llvm::Regex(IncludeRegexPattern).match(Replace.getReplacementText()); 1878 } 1879 1880 inline bool isHeaderDeletion(const tooling::Replacement &Replace) { 1881 return Replace.getOffset() == UINT_MAX && Replace.getLength() == 1; 1882 } 1883 1884 // Returns the offset after skipping a sequence of tokens, matched by \p 1885 // GetOffsetAfterSequence, from the start of the code. 1886 // \p GetOffsetAfterSequence should be a function that matches a sequence of 1887 // tokens and returns an offset after the sequence. 1888 unsigned getOffsetAfterTokenSequence( 1889 StringRef FileName, StringRef Code, const FormatStyle &Style, 1890 llvm::function_ref<unsigned(const SourceManager &, Lexer &, Token &)> 1891 GetOffsetAfterSequence) { 1892 std::unique_ptr<Environment> Env = 1893 Environment::CreateVirtualEnvironment(Code, FileName, /*Ranges=*/{}); 1894 const SourceManager &SourceMgr = Env->getSourceManager(); 1895 Lexer Lex(Env->getFileID(), SourceMgr.getBuffer(Env->getFileID()), SourceMgr, 1896 getFormattingLangOpts(Style)); 1897 Token Tok; 1898 // Get the first token. 1899 Lex.LexFromRawLexer(Tok); 1900 return GetOffsetAfterSequence(SourceMgr, Lex, Tok); 1901 } 1902 1903 // Check if a sequence of tokens is like "#<Name> <raw_identifier>". If it is, 1904 // \p Tok will be the token after this directive; otherwise, it can be any token 1905 // after the given \p Tok (including \p Tok). 1906 bool checkAndConsumeDirectiveWithName(Lexer &Lex, StringRef Name, Token &Tok) { 1907 bool Matched = Tok.is(tok::hash) && !Lex.LexFromRawLexer(Tok) && 1908 Tok.is(tok::raw_identifier) && 1909 Tok.getRawIdentifier() == Name && !Lex.LexFromRawLexer(Tok) && 1910 Tok.is(tok::raw_identifier); 1911 if (Matched) 1912 Lex.LexFromRawLexer(Tok); 1913 return Matched; 1914 } 1915 1916 void skipComments(Lexer &Lex, Token &Tok) { 1917 while (Tok.is(tok::comment)) 1918 if (Lex.LexFromRawLexer(Tok)) 1919 return; 1920 } 1921 1922 // Returns the offset after header guard directives and any comments 1923 // before/after header guards. If no header guard presents in the code, this 1924 // will returns the offset after skipping all comments from the start of the 1925 // code. 1926 unsigned getOffsetAfterHeaderGuardsAndComments(StringRef FileName, 1927 StringRef Code, 1928 const FormatStyle &Style) { 1929 return getOffsetAfterTokenSequence( 1930 FileName, Code, Style, 1931 [](const SourceManager &SM, Lexer &Lex, Token Tok) { 1932 skipComments(Lex, Tok); 1933 unsigned InitialOffset = SM.getFileOffset(Tok.getLocation()); 1934 if (checkAndConsumeDirectiveWithName(Lex, "ifndef", Tok)) { 1935 skipComments(Lex, Tok); 1936 if (checkAndConsumeDirectiveWithName(Lex, "define", Tok)) 1937 return SM.getFileOffset(Tok.getLocation()); 1938 } 1939 return InitialOffset; 1940 }); 1941 } 1942 1943 // Check if a sequence of tokens is like 1944 // "#include ("header.h" | <header.h>)". 1945 // If it is, \p Tok will be the token after this directive; otherwise, it can be 1946 // any token after the given \p Tok (including \p Tok). 1947 bool checkAndConsumeInclusiveDirective(Lexer &Lex, Token &Tok) { 1948 auto Matched = [&]() { 1949 Lex.LexFromRawLexer(Tok); 1950 return true; 1951 }; 1952 if (Tok.is(tok::hash) && !Lex.LexFromRawLexer(Tok) && 1953 Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "include") { 1954 if (Lex.LexFromRawLexer(Tok)) 1955 return false; 1956 if (Tok.is(tok::string_literal)) 1957 return Matched(); 1958 if (Tok.is(tok::less)) { 1959 while (!Lex.LexFromRawLexer(Tok) && Tok.isNot(tok::greater)) { 1960 } 1961 if (Tok.is(tok::greater)) 1962 return Matched(); 1963 } 1964 } 1965 return false; 1966 } 1967 1968 // Returns the offset of the last #include directive after which a new 1969 // #include can be inserted. This ignores #include's after the #include block(s) 1970 // in the beginning of a file to avoid inserting headers into code sections 1971 // where new #include's should not be added by default. 1972 // These code sections include: 1973 // - raw string literals (containing #include). 1974 // - #if blocks. 1975 // - Special #include's among declarations (e.g. functions). 1976 // 1977 // If no #include after which a new #include can be inserted, this returns the 1978 // offset after skipping all comments from the start of the code. 1979 // Inserting after an #include is not allowed if it comes after code that is not 1980 // #include (e.g. pre-processing directive that is not #include, declarations). 1981 unsigned getMaxHeaderInsertionOffset(StringRef FileName, StringRef Code, 1982 const FormatStyle &Style) { 1983 return getOffsetAfterTokenSequence( 1984 FileName, Code, Style, 1985 [](const SourceManager &SM, Lexer &Lex, Token Tok) { 1986 skipComments(Lex, Tok); 1987 unsigned MaxOffset = SM.getFileOffset(Tok.getLocation()); 1988 while (checkAndConsumeInclusiveDirective(Lex, Tok)) 1989 MaxOffset = SM.getFileOffset(Tok.getLocation()); 1990 return MaxOffset; 1991 }); 1992 } 1993 1994 bool isDeletedHeader(llvm::StringRef HeaderName, 1995 const std::set<llvm::StringRef> &HeadersToDelete) { 1996 return HeadersToDelete.count(HeaderName) || 1997 HeadersToDelete.count(HeaderName.trim("\"<>")); 1998 } 1999 2000 // FIXME: insert empty lines between newly created blocks. 2001 tooling::Replacements 2002 fixCppIncludeInsertions(StringRef Code, const tooling::Replacements &Replaces, 2003 const FormatStyle &Style) { 2004 if (!Style.isCpp()) 2005 return Replaces; 2006 2007 tooling::Replacements HeaderInsertions; 2008 std::set<llvm::StringRef> HeadersToDelete; 2009 tooling::Replacements Result; 2010 for (const auto &R : Replaces) { 2011 if (isHeaderInsertion(R)) { 2012 // Replacements from \p Replaces must be conflict-free already, so we can 2013 // simply consume the error. 2014 llvm::consumeError(HeaderInsertions.add(R)); 2015 } else if (isHeaderDeletion(R)) { 2016 HeadersToDelete.insert(R.getReplacementText()); 2017 } else if (R.getOffset() == UINT_MAX) { 2018 llvm::errs() << "Insertions other than header #include insertion are " 2019 "not supported! " 2020 << R.getReplacementText() << "\n"; 2021 } else { 2022 llvm::consumeError(Result.add(R)); 2023 } 2024 } 2025 if (HeaderInsertions.empty() && HeadersToDelete.empty()) 2026 return Replaces; 2027 2028 llvm::Regex IncludeRegex(IncludeRegexPattern); 2029 llvm::Regex DefineRegex(R"(^[\t\ ]*#[\t\ ]*define[\t\ ]*[^\\]*$)"); 2030 SmallVector<StringRef, 4> Matches; 2031 2032 StringRef FileName = Replaces.begin()->getFilePath(); 2033 IncludeCategoryManager Categories(Style, FileName); 2034 2035 // Record the offset of the end of the last include in each category. 2036 std::map<int, int> CategoryEndOffsets; 2037 // All possible priorities. 2038 // Add 0 for main header and INT_MAX for headers that are not in any category. 2039 std::set<int> Priorities = {0, INT_MAX}; 2040 for (const auto &Category : Style.IncludeCategories) 2041 Priorities.insert(Category.Priority); 2042 int FirstIncludeOffset = -1; 2043 // All new headers should be inserted after this offset. 2044 unsigned MinInsertOffset = 2045 getOffsetAfterHeaderGuardsAndComments(FileName, Code, Style); 2046 StringRef TrimmedCode = Code.drop_front(MinInsertOffset); 2047 // Max insertion offset in the original code. 2048 unsigned MaxInsertOffset = 2049 MinInsertOffset + 2050 getMaxHeaderInsertionOffset(FileName, TrimmedCode, Style); 2051 SmallVector<StringRef, 32> Lines; 2052 TrimmedCode.split(Lines, '\n'); 2053 unsigned Offset = MinInsertOffset; 2054 unsigned NextLineOffset; 2055 std::set<StringRef> ExistingIncludes; 2056 for (auto Line : Lines) { 2057 NextLineOffset = std::min(Code.size(), Offset + Line.size() + 1); 2058 if (IncludeRegex.match(Line, &Matches)) { 2059 // The header name with quotes or angle brackets. 2060 StringRef IncludeName = Matches[2]; 2061 ExistingIncludes.insert(IncludeName); 2062 // Only record the offset of current #include if we can insert after it. 2063 if (Offset <= MaxInsertOffset) { 2064 int Category = Categories.getIncludePriority( 2065 IncludeName, /*CheckMainHeader=*/FirstIncludeOffset < 0); 2066 CategoryEndOffsets[Category] = NextLineOffset; 2067 if (FirstIncludeOffset < 0) 2068 FirstIncludeOffset = Offset; 2069 } 2070 if (isDeletedHeader(IncludeName, HeadersToDelete)) { 2071 // If this is the last line without trailing newline, we need to make 2072 // sure we don't delete across the file boundary. 2073 unsigned Length = std::min(Line.size() + 1, Code.size() - Offset); 2074 llvm::Error Err = 2075 Result.add(tooling::Replacement(FileName, Offset, Length, "")); 2076 if (Err) { 2077 // Ignore the deletion on conflict. 2078 llvm::errs() << "Failed to add header deletion replacement for " 2079 << IncludeName << ": " << llvm::toString(std::move(Err)) 2080 << "\n"; 2081 } 2082 } 2083 } 2084 Offset = NextLineOffset; 2085 } 2086 2087 // Populate CategoryEndOfssets: 2088 // - Ensure that CategoryEndOffset[Highest] is always populated. 2089 // - If CategoryEndOffset[Priority] isn't set, use the next higher value that 2090 // is set, up to CategoryEndOffset[Highest]. 2091 auto Highest = Priorities.begin(); 2092 if (CategoryEndOffsets.find(*Highest) == CategoryEndOffsets.end()) { 2093 if (FirstIncludeOffset >= 0) 2094 CategoryEndOffsets[*Highest] = FirstIncludeOffset; 2095 else 2096 CategoryEndOffsets[*Highest] = MinInsertOffset; 2097 } 2098 // By this point, CategoryEndOffset[Highest] is always set appropriately: 2099 // - to an appropriate location before/after existing #includes, or 2100 // - to right after the header guard, or 2101 // - to the beginning of the file. 2102 for (auto I = ++Priorities.begin(), E = Priorities.end(); I != E; ++I) 2103 if (CategoryEndOffsets.find(*I) == CategoryEndOffsets.end()) 2104 CategoryEndOffsets[*I] = CategoryEndOffsets[*std::prev(I)]; 2105 2106 bool NeedNewLineAtEnd = !Code.empty() && Code.back() != '\n'; 2107 for (const auto &R : HeaderInsertions) { 2108 auto IncludeDirective = R.getReplacementText(); 2109 bool Matched = IncludeRegex.match(IncludeDirective, &Matches); 2110 assert(Matched && "Header insertion replacement must have replacement text " 2111 "'#include ...'"); 2112 (void)Matched; 2113 auto IncludeName = Matches[2]; 2114 if (ExistingIncludes.find(IncludeName) != ExistingIncludes.end()) { 2115 DEBUG(llvm::dbgs() << "Skip adding existing include : " << IncludeName 2116 << "\n"); 2117 continue; 2118 } 2119 int Category = 2120 Categories.getIncludePriority(IncludeName, /*CheckMainHeader=*/true); 2121 Offset = CategoryEndOffsets[Category]; 2122 std::string NewInclude = !IncludeDirective.endswith("\n") 2123 ? (IncludeDirective + "\n").str() 2124 : IncludeDirective.str(); 2125 // When inserting headers at end of the code, also append '\n' to the code 2126 // if it does not end with '\n'. 2127 if (NeedNewLineAtEnd && Offset == Code.size()) { 2128 NewInclude = "\n" + NewInclude; 2129 NeedNewLineAtEnd = false; 2130 } 2131 auto NewReplace = tooling::Replacement(FileName, Offset, 0, NewInclude); 2132 auto Err = Result.add(NewReplace); 2133 if (Err) { 2134 llvm::consumeError(std::move(Err)); 2135 unsigned NewOffset = Result.getShiftedCodePosition(Offset); 2136 NewReplace = tooling::Replacement(FileName, NewOffset, 0, NewInclude); 2137 Result = Result.merge(tooling::Replacements(NewReplace)); 2138 } 2139 } 2140 return Result; 2141 } 2142 2143 } // anonymous namespace 2144 2145 llvm::Expected<tooling::Replacements> 2146 cleanupAroundReplacements(StringRef Code, const tooling::Replacements &Replaces, 2147 const FormatStyle &Style) { 2148 // We need to use lambda function here since there are two versions of 2149 // `cleanup`. 2150 auto Cleanup = [](const FormatStyle &Style, StringRef Code, 2151 std::vector<tooling::Range> Ranges, 2152 StringRef FileName) -> tooling::Replacements { 2153 return cleanup(Style, Code, Ranges, FileName); 2154 }; 2155 // Make header insertion replacements insert new headers into correct blocks. 2156 tooling::Replacements NewReplaces = 2157 fixCppIncludeInsertions(Code, Replaces, Style); 2158 return processReplacements(Cleanup, Code, NewReplaces, Style); 2159 } 2160 2161 namespace internal { 2162 std::pair<tooling::Replacements, unsigned> 2163 reformat(const FormatStyle &Style, StringRef Code, 2164 ArrayRef<tooling::Range> Ranges, unsigned FirstStartColumn, 2165 unsigned NextStartColumn, unsigned LastStartColumn, StringRef FileName, 2166 FormattingAttemptStatus *Status) { 2167 FormatStyle Expanded = expandPresets(Style); 2168 if (Expanded.DisableFormat) 2169 return {tooling::Replacements(), 0}; 2170 if (isLikelyXml(Code)) 2171 return {tooling::Replacements(), 0}; 2172 if (Expanded.Language == FormatStyle::LK_JavaScript && isMpegTS(Code)) 2173 return {tooling::Replacements(), 0}; 2174 2175 typedef std::function<std::pair<tooling::Replacements, unsigned>( 2176 const Environment &)> 2177 AnalyzerPass; 2178 SmallVector<AnalyzerPass, 4> Passes; 2179 2180 if (Style.Language == FormatStyle::LK_Cpp) { 2181 if (Style.FixNamespaceComments) 2182 Passes.emplace_back([&](const Environment &Env) { 2183 return NamespaceEndCommentsFixer(Env, Expanded).process(); 2184 }); 2185 2186 if (Style.SortUsingDeclarations) 2187 Passes.emplace_back([&](const Environment &Env) { 2188 return UsingDeclarationsSorter(Env, Expanded).process(); 2189 }); 2190 } 2191 2192 if (Style.Language == FormatStyle::LK_JavaScript && 2193 Style.JavaScriptQuotes != FormatStyle::JSQS_Leave) 2194 Passes.emplace_back([&](const Environment &Env) { 2195 return JavaScriptRequoter(Env, Expanded).process(); 2196 }); 2197 2198 Passes.emplace_back([&](const Environment &Env) { 2199 return Formatter(Env, Expanded, Status).process(); 2200 }); 2201 2202 std::unique_ptr<Environment> Env = Environment::CreateVirtualEnvironment( 2203 Code, FileName, Ranges, FirstStartColumn, NextStartColumn, 2204 LastStartColumn); 2205 llvm::Optional<std::string> CurrentCode = None; 2206 tooling::Replacements Fixes; 2207 unsigned Penalty = 0; 2208 for (size_t I = 0, E = Passes.size(); I < E; ++I) { 2209 std::pair<tooling::Replacements, unsigned> PassFixes = Passes[I](*Env); 2210 auto NewCode = applyAllReplacements( 2211 CurrentCode ? StringRef(*CurrentCode) : Code, PassFixes.first); 2212 if (NewCode) { 2213 Fixes = Fixes.merge(PassFixes.first); 2214 Penalty += PassFixes.second; 2215 if (I + 1 < E) { 2216 CurrentCode = std::move(*NewCode); 2217 Env = Environment::CreateVirtualEnvironment( 2218 *CurrentCode, FileName, 2219 tooling::calculateRangesAfterReplacements(Fixes, Ranges), 2220 FirstStartColumn, NextStartColumn, LastStartColumn); 2221 } 2222 } 2223 } 2224 2225 return {Fixes, Penalty}; 2226 } 2227 } // namespace internal 2228 2229 tooling::Replacements reformat(const FormatStyle &Style, StringRef Code, 2230 ArrayRef<tooling::Range> Ranges, 2231 StringRef FileName, 2232 FormattingAttemptStatus *Status) { 2233 return internal::reformat(Style, Code, Ranges, 2234 /*FirstStartColumn=*/0, 2235 /*NextStartColumn=*/0, 2236 /*LastStartColumn=*/0, FileName, Status) 2237 .first; 2238 } 2239 2240 tooling::Replacements cleanup(const FormatStyle &Style, StringRef Code, 2241 ArrayRef<tooling::Range> Ranges, 2242 StringRef FileName) { 2243 // cleanups only apply to C++ (they mostly concern ctor commas etc.) 2244 if (Style.Language != FormatStyle::LK_Cpp) 2245 return tooling::Replacements(); 2246 std::unique_ptr<Environment> Env = 2247 Environment::CreateVirtualEnvironment(Code, FileName, Ranges); 2248 Cleaner Clean(*Env, Style); 2249 return Clean.process().first; 2250 } 2251 2252 tooling::Replacements reformat(const FormatStyle &Style, StringRef Code, 2253 ArrayRef<tooling::Range> Ranges, 2254 StringRef FileName, bool *IncompleteFormat) { 2255 FormattingAttemptStatus Status; 2256 auto Result = reformat(Style, Code, Ranges, FileName, &Status); 2257 if (!Status.FormatComplete) 2258 *IncompleteFormat = true; 2259 return Result; 2260 } 2261 2262 tooling::Replacements fixNamespaceEndComments(const FormatStyle &Style, 2263 StringRef Code, 2264 ArrayRef<tooling::Range> Ranges, 2265 StringRef FileName) { 2266 std::unique_ptr<Environment> Env = 2267 Environment::CreateVirtualEnvironment(Code, FileName, Ranges); 2268 NamespaceEndCommentsFixer Fix(*Env, Style); 2269 return Fix.process().first; 2270 } 2271 2272 tooling::Replacements sortUsingDeclarations(const FormatStyle &Style, 2273 StringRef Code, 2274 ArrayRef<tooling::Range> Ranges, 2275 StringRef FileName) { 2276 std::unique_ptr<Environment> Env = 2277 Environment::CreateVirtualEnvironment(Code, FileName, Ranges); 2278 UsingDeclarationsSorter Sorter(*Env, Style); 2279 return Sorter.process().first; 2280 } 2281 2282 LangOptions getFormattingLangOpts(const FormatStyle &Style) { 2283 LangOptions LangOpts; 2284 LangOpts.CPlusPlus = 1; 2285 LangOpts.CPlusPlus11 = Style.Standard == FormatStyle::LS_Cpp03 ? 0 : 1; 2286 LangOpts.CPlusPlus14 = Style.Standard == FormatStyle::LS_Cpp03 ? 0 : 1; 2287 LangOpts.CPlusPlus17 = Style.Standard == FormatStyle::LS_Cpp03 ? 0 : 1; 2288 LangOpts.CPlusPlus2a = Style.Standard == FormatStyle::LS_Cpp03 ? 0 : 1; 2289 LangOpts.LineComment = 1; 2290 bool AlternativeOperators = Style.isCpp(); 2291 LangOpts.CXXOperatorNames = AlternativeOperators ? 1 : 0; 2292 LangOpts.Bool = 1; 2293 LangOpts.ObjC1 = 1; 2294 LangOpts.ObjC2 = 1; 2295 LangOpts.MicrosoftExt = 1; // To get kw___try, kw___finally. 2296 LangOpts.DeclSpecKeyword = 1; // To get __declspec. 2297 return LangOpts; 2298 } 2299 2300 const char *StyleOptionHelpDescription = 2301 "Coding style, currently supports:\n" 2302 " LLVM, Google, Chromium, Mozilla, WebKit.\n" 2303 "Use -style=file to load style configuration from\n" 2304 ".clang-format file located in one of the parent\n" 2305 "directories of the source file (or current\n" 2306 "directory for stdin).\n" 2307 "Use -style=\"{key: value, ...}\" to set specific\n" 2308 "parameters, e.g.:\n" 2309 " -style=\"{BasedOnStyle: llvm, IndentWidth: 8}\""; 2310 2311 static FormatStyle::LanguageKind getLanguageByFileName(StringRef FileName) { 2312 if (FileName.endswith(".java")) 2313 return FormatStyle::LK_Java; 2314 if (FileName.endswith_lower(".js") || FileName.endswith_lower(".ts")) 2315 return FormatStyle::LK_JavaScript; // JavaScript or TypeScript. 2316 if (FileName.endswith(".m") || FileName.endswith(".mm")) 2317 return FormatStyle::LK_ObjC; 2318 if (FileName.endswith_lower(".proto") || 2319 FileName.endswith_lower(".protodevel")) 2320 return FormatStyle::LK_Proto; 2321 if (FileName.endswith_lower(".textpb") || 2322 FileName.endswith_lower(".pb.txt") || 2323 FileName.endswith_lower(".textproto") || 2324 FileName.endswith_lower(".asciipb")) 2325 return FormatStyle::LK_TextProto; 2326 if (FileName.endswith_lower(".td")) 2327 return FormatStyle::LK_TableGen; 2328 return FormatStyle::LK_Cpp; 2329 } 2330 2331 FormatStyle::LanguageKind guessLanguage(StringRef FileName, StringRef Code) { 2332 const auto GuessedLanguage = getLanguageByFileName(FileName); 2333 if (GuessedLanguage == FormatStyle::LK_Cpp) { 2334 auto Extension = llvm::sys::path::extension(FileName); 2335 // If there's no file extension (or it's .h), we need to check the contents 2336 // of the code to see if it contains Objective-C. 2337 if (Extension.empty() || Extension == ".h") { 2338 auto NonEmptyFileName = FileName.empty() ? "guess.h" : FileName; 2339 std::unique_ptr<Environment> Env = 2340 Environment::CreateVirtualEnvironment(Code, NonEmptyFileName, /*Ranges=*/{}); 2341 ObjCHeaderStyleGuesser Guesser(*Env, getLLVMStyle()); 2342 Guesser.process(); 2343 if (Guesser.isObjC()) 2344 return FormatStyle::LK_ObjC; 2345 } 2346 } 2347 return GuessedLanguage; 2348 } 2349 2350 llvm::Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName, 2351 StringRef FallbackStyleName, 2352 StringRef Code, vfs::FileSystem *FS) { 2353 if (!FS) { 2354 FS = vfs::getRealFileSystem().get(); 2355 } 2356 FormatStyle Style = getLLVMStyle(); 2357 Style.Language = guessLanguage(FileName, Code); 2358 2359 FormatStyle FallbackStyle = getNoStyle(); 2360 if (!getPredefinedStyle(FallbackStyleName, Style.Language, &FallbackStyle)) 2361 return make_string_error("Invalid fallback style \"" + FallbackStyleName); 2362 2363 if (StyleName.startswith("{")) { 2364 // Parse YAML/JSON style from the command line. 2365 if (std::error_code ec = parseConfiguration(StyleName, &Style)) 2366 return make_string_error("Error parsing -style: " + ec.message()); 2367 return Style; 2368 } 2369 2370 if (!StyleName.equals_lower("file")) { 2371 if (!getPredefinedStyle(StyleName, Style.Language, &Style)) 2372 return make_string_error("Invalid value for -style"); 2373 return Style; 2374 } 2375 2376 // Look for .clang-format/_clang-format file in the file's parent directories. 2377 SmallString<128> UnsuitableConfigFiles; 2378 SmallString<128> Path(FileName); 2379 if (std::error_code EC = FS->makeAbsolute(Path)) 2380 return make_string_error(EC.message()); 2381 2382 for (StringRef Directory = Path; !Directory.empty(); 2383 Directory = llvm::sys::path::parent_path(Directory)) { 2384 2385 auto Status = FS->status(Directory); 2386 if (!Status || 2387 Status->getType() != llvm::sys::fs::file_type::directory_file) { 2388 continue; 2389 } 2390 2391 SmallString<128> ConfigFile(Directory); 2392 2393 llvm::sys::path::append(ConfigFile, ".clang-format"); 2394 DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n"); 2395 2396 Status = FS->status(ConfigFile.str()); 2397 bool FoundConfigFile = 2398 Status && (Status->getType() == llvm::sys::fs::file_type::regular_file); 2399 if (!FoundConfigFile) { 2400 // Try _clang-format too, since dotfiles are not commonly used on Windows. 2401 ConfigFile = Directory; 2402 llvm::sys::path::append(ConfigFile, "_clang-format"); 2403 DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n"); 2404 Status = FS->status(ConfigFile.str()); 2405 FoundConfigFile = Status && (Status->getType() == 2406 llvm::sys::fs::file_type::regular_file); 2407 } 2408 2409 if (FoundConfigFile) { 2410 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text = 2411 FS->getBufferForFile(ConfigFile.str()); 2412 if (std::error_code EC = Text.getError()) 2413 return make_string_error(EC.message()); 2414 if (std::error_code ec = 2415 parseConfiguration(Text.get()->getBuffer(), &Style)) { 2416 if (ec == ParseError::Unsuitable) { 2417 if (!UnsuitableConfigFiles.empty()) 2418 UnsuitableConfigFiles.append(", "); 2419 UnsuitableConfigFiles.append(ConfigFile); 2420 continue; 2421 } 2422 return make_string_error("Error reading " + ConfigFile + ": " + 2423 ec.message()); 2424 } 2425 DEBUG(llvm::dbgs() << "Using configuration file " << ConfigFile << "\n"); 2426 return Style; 2427 } 2428 } 2429 if (!UnsuitableConfigFiles.empty()) 2430 return make_string_error("Configuration file(s) do(es) not support " + 2431 getLanguageName(Style.Language) + ": " + 2432 UnsuitableConfigFiles); 2433 return FallbackStyle; 2434 } 2435 2436 } // namespace format 2437 } // namespace clang 2438