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