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