diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-07-31 21:22:58 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-07-31 21:22:58 +0000 |
commit | 5ffd83dbcc34f10e07f6d3e968ae6365869615f4 (patch) | |
tree | 0e9f5cf729dde39f949698fddef45a34e2bc7f44 /contrib/llvm-project/clang/lib/Format/Format.cpp | |
parent | 1799696096df87b52968b8996d00c91e0a5de8d9 (diff) | |
parent | cfca06d7963fa0909f90483b42a6d7d194d01e08 (diff) |
Notes
Diffstat (limited to 'contrib/llvm-project/clang/lib/Format/Format.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/Format/Format.cpp | 271 |
1 files changed, 235 insertions, 36 deletions
diff --git a/contrib/llvm-project/clang/lib/Format/Format.cpp b/contrib/llvm-project/clang/lib/Format/Format.cpp index f12bca48c630..0d277a6464af 100644 --- a/contrib/llvm-project/clang/lib/Format/Format.cpp +++ b/contrib/llvm-project/clang/lib/Format/Format.cpp @@ -14,6 +14,7 @@ #include "clang/Format/Format.h" #include "AffectedRangeManager.h" +#include "BreakableToken.h" #include "ContinuationIndenter.h" #include "FormatInternal.h" #include "FormatTokenLexer.h" @@ -93,6 +94,7 @@ template <> struct ScalarEnumerationTraits<FormatStyle::UseTabStyle> { IO.enumCase(Value, "ForIndentation", FormatStyle::UT_ForIndentation); IO.enumCase(Value, "ForContinuationAndIndentation", FormatStyle::UT_ForContinuationAndIndentation); + IO.enumCase(Value, "AlignWithSpaces", FormatStyle::UT_AlignWithSpaces); } }; @@ -157,6 +159,13 @@ template <> struct ScalarEnumerationTraits<FormatStyle::BinPackStyle> { } }; +template <> struct ScalarEnumerationTraits<FormatStyle::TrailingCommaStyle> { + static void enumeration(IO &IO, FormatStyle::TrailingCommaStyle &Value) { + IO.enumCase(Value, "None", FormatStyle::TCS_None); + IO.enumCase(Value, "Wrapped", FormatStyle::TCS_Wrapped); + } +}; + template <> struct ScalarEnumerationTraits<FormatStyle::BinaryOperatorStyle> { static void enumeration(IO &IO, FormatStyle::BinaryOperatorStyle &Value) { IO.enumCase(Value, "All", FormatStyle::BOS_All); @@ -187,11 +196,13 @@ struct ScalarEnumerationTraits< static void enumeration(IO &IO, FormatStyle::BraceWrappingAfterControlStatementStyle &Value) { - IO.enumCase(Value, "false", FormatStyle::BWACS_Never); - IO.enumCase(Value, "true", FormatStyle::BWACS_Always); IO.enumCase(Value, "Never", FormatStyle::BWACS_Never); IO.enumCase(Value, "MultiLine", FormatStyle::BWACS_MultiLine); IO.enumCase(Value, "Always", FormatStyle::BWACS_Always); + + // For backward compatibility. + IO.enumCase(Value, "false", FormatStyle::BWACS_Never); + IO.enumCase(Value, "true", FormatStyle::BWACS_Always); } }; @@ -225,6 +236,17 @@ struct ScalarEnumerationTraits<FormatStyle::PPDirectiveIndentStyle> { }; template <> +struct ScalarEnumerationTraits<FormatStyle::IndentExternBlockStyle> { + static void enumeration(IO &IO, FormatStyle::IndentExternBlockStyle &Value) { + IO.enumCase(Value, "AfterExternBlock", FormatStyle::IEBS_AfterExternBlock); + IO.enumCase(Value, "Indent", FormatStyle::IEBS_Indent); + IO.enumCase(Value, "NoIndent", FormatStyle::IEBS_NoIndent); + IO.enumCase(Value, "true", FormatStyle::IEBS_Indent); + IO.enumCase(Value, "false", FormatStyle::IEBS_NoIndent); + } +}; + +template <> struct ScalarEnumerationTraits<FormatStyle::ReturnTypeBreakingStyle> { static void enumeration(IO &IO, FormatStyle::ReturnTypeBreakingStyle &Value) { IO.enumCase(Value, "None", FormatStyle::RTBS_None); @@ -300,6 +322,19 @@ struct ScalarEnumerationTraits<FormatStyle::EscapedNewlineAlignmentStyle> { } }; +template <> struct ScalarEnumerationTraits<FormatStyle::OperandAlignmentStyle> { + static void enumeration(IO &IO, FormatStyle::OperandAlignmentStyle &Value) { + IO.enumCase(Value, "DontAlign", FormatStyle::OAS_DontAlign); + IO.enumCase(Value, "Align", FormatStyle::OAS_Align); + IO.enumCase(Value, "AlignAfterOperator", + FormatStyle::OAS_AlignAfterOperator); + + // For backward compatibility. + IO.enumCase(Value, "true", FormatStyle::OAS_Align); + IO.enumCase(Value, "false", FormatStyle::OAS_DontAlign); + } +}; + template <> struct ScalarEnumerationTraits<FormatStyle::PointerAlignmentStyle> { static void enumeration(IO &IO, FormatStyle::PointerAlignmentStyle &Value) { IO.enumCase(Value, "Middle", FormatStyle::PAS_Middle); @@ -319,6 +354,8 @@ struct ScalarEnumerationTraits<FormatStyle::SpaceBeforeParensOptions> { IO.enumCase(Value, "Never", FormatStyle::SBPO_Never); IO.enumCase(Value, "ControlStatements", FormatStyle::SBPO_ControlStatements); + IO.enumCase(Value, "ControlStatementsExceptForEachMacros", + FormatStyle::SBPO_ControlStatementsExceptForEachMacros); IO.enumCase(Value, "NonEmptyParentheses", FormatStyle::SBPO_NonEmptyParentheses); IO.enumCase(Value, "Always", FormatStyle::SBPO_Always); @@ -378,6 +415,8 @@ template <> struct MappingTraits<FormatStyle> { IO.mapOptional("AlignConsecutiveMacros", Style.AlignConsecutiveMacros); IO.mapOptional("AlignConsecutiveAssignments", Style.AlignConsecutiveAssignments); + IO.mapOptional("AlignConsecutiveBitFields", + Style.AlignConsecutiveBitFields); IO.mapOptional("AlignConsecutiveDeclarations", Style.AlignConsecutiveDeclarations); IO.mapOptional("AlignEscapedNewlines", Style.AlignEscapedNewlines); @@ -389,6 +428,8 @@ template <> struct MappingTraits<FormatStyle> { Style.AllowAllConstructorInitializersOnNextLine); IO.mapOptional("AllowAllParametersOfDeclarationOnNextLine", Style.AllowAllParametersOfDeclarationOnNextLine); + IO.mapOptional("AllowShortEnumsOnASingleLine", + Style.AllowShortEnumsOnASingleLine); IO.mapOptional("AllowShortBlocksOnASingleLine", Style.AllowShortBlocksOnASingleLine); IO.mapOptional("AllowShortCaseLabelsOnASingleLine", @@ -480,11 +521,14 @@ template <> struct MappingTraits<FormatStyle> { IO.mapOptional("IncludeIsMainSourceRegex", Style.IncludeStyle.IncludeIsMainSourceRegex); IO.mapOptional("IndentCaseLabels", Style.IndentCaseLabels); + IO.mapOptional("IndentCaseBlocks", Style.IndentCaseBlocks); IO.mapOptional("IndentGotoLabels", Style.IndentGotoLabels); IO.mapOptional("IndentPPDirectives", Style.IndentPPDirectives); + IO.mapOptional("IndentExternBlock", Style.IndentExternBlock); IO.mapOptional("IndentWidth", Style.IndentWidth); IO.mapOptional("IndentWrappedFunctionNames", Style.IndentWrappedFunctionNames); + IO.mapOptional("InsertTrailingCommas", Style.InsertTrailingCommas); IO.mapOptional("JavaImportGroups", Style.JavaImportGroups); IO.mapOptional("JavaScriptQuotes", Style.JavaScriptQuotes); IO.mapOptional("JavaScriptWrapImports", Style.JavaScriptWrapImports); @@ -497,6 +541,8 @@ template <> struct MappingTraits<FormatStyle> { IO.mapOptional("NamespaceMacros", Style.NamespaceMacros); IO.mapOptional("ObjCBinPackProtocolList", Style.ObjCBinPackProtocolList); IO.mapOptional("ObjCBlockIndentWidth", Style.ObjCBlockIndentWidth); + IO.mapOptional("ObjCBreakBeforeNestedBlockParam", + Style.ObjCBreakBeforeNestedBlockParam); IO.mapOptional("ObjCSpaceAfterProperty", Style.ObjCSpaceAfterProperty); IO.mapOptional("ObjCSpaceBeforeProtocolList", Style.ObjCSpaceBeforeProtocolList); @@ -553,6 +599,8 @@ template <> struct MappingTraits<FormatStyle> { IO.mapOptional("TypenameMacros", Style.TypenameMacros); IO.mapOptional("UseCRLF", Style.UseCRLF); IO.mapOptional("UseTab", Style.UseTab); + IO.mapOptional("WhitespaceSensitiveMacros", + Style.WhitespaceSensitiveMacros); } }; @@ -570,6 +618,8 @@ template <> struct MappingTraits<FormatStyle::BraceWrappingFlags> { IO.mapOptional("AfterExternBlock", Wrapping.AfterExternBlock); IO.mapOptional("BeforeCatch", Wrapping.BeforeCatch); IO.mapOptional("BeforeElse", Wrapping.BeforeElse); + IO.mapOptional("BeforeLambdaBody", Wrapping.BeforeLambdaBody); + IO.mapOptional("BeforeWhile", Wrapping.BeforeWhile); IO.mapOptional("IndentBraces", Wrapping.IndentBraces); IO.mapOptional("SplitEmptyFunction", Wrapping.SplitEmptyFunction); IO.mapOptional("SplitEmptyRecord", Wrapping.SplitEmptyRecord); @@ -643,6 +693,8 @@ std::string ParseErrorCategory::message(int EV) const { return "Invalid argument"; case ParseError::Unsuitable: return "Unsuitable"; + case ParseError::BinPackTrailingCommaConflict: + return "trailing comma insertion cannot be used with bin packing"; } llvm_unreachable("unexpected parse error"); } @@ -651,12 +703,24 @@ static FormatStyle expandPresets(const FormatStyle &Style) { if (Style.BreakBeforeBraces == FormatStyle::BS_Custom) return Style; FormatStyle Expanded = Style; - Expanded.BraceWrapping = {false, false, FormatStyle::BWACS_Never, - false, false, false, - false, false, false, - false, false, false, - false, true, true, - true}; + Expanded.BraceWrapping = {/*AfterCaseLabel=*/false, + /*AfterClass=*/false, + /*AfterControlStatement=*/FormatStyle::BWACS_Never, + /*AfterEnum=*/false, + /*AfterFunction=*/false, + /*AfterNamespace=*/false, + /*AfterObjCDeclaration=*/false, + /*AfterStruct=*/false, + /*AfterUnion=*/false, + /*AfterExternBlock=*/false, + /*BeforeCatch=*/false, + /*BeforeElse=*/false, + /*BeforeLambdaBody=*/false, + /*BeforeWhile=*/false, + /*IndentBraces=*/false, + /*SplitEmptyFunction=*/true, + /*SplitEmptyRecord=*/true, + /*SplitEmptyNamespace=*/true}; switch (Style.BreakBeforeBraces) { case FormatStyle::BS_Linux: Expanded.BraceWrapping.AfterClass = true; @@ -670,6 +734,7 @@ static FormatStyle expandPresets(const FormatStyle &Style) { Expanded.BraceWrapping.AfterStruct = true; Expanded.BraceWrapping.AfterUnion = true; Expanded.BraceWrapping.AfterExternBlock = true; + Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock; Expanded.BraceWrapping.SplitEmptyFunction = true; Expanded.BraceWrapping.SplitEmptyRecord = false; break; @@ -689,6 +754,7 @@ static FormatStyle expandPresets(const FormatStyle &Style) { Expanded.BraceWrapping.AfterStruct = true; Expanded.BraceWrapping.AfterUnion = true; Expanded.BraceWrapping.AfterExternBlock = true; + Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock; Expanded.BraceWrapping.BeforeCatch = true; Expanded.BraceWrapping.BeforeElse = true; break; @@ -702,16 +768,32 @@ static FormatStyle expandPresets(const FormatStyle &Style) { Expanded.BraceWrapping.AfterObjCDeclaration = true; Expanded.BraceWrapping.AfterStruct = true; Expanded.BraceWrapping.AfterExternBlock = true; + Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock; Expanded.BraceWrapping.BeforeCatch = true; Expanded.BraceWrapping.BeforeElse = true; + Expanded.BraceWrapping.BeforeLambdaBody = true; break; case FormatStyle::BS_GNU: - Expanded.BraceWrapping = {true, true, FormatStyle::BWACS_Always, - true, true, true, - true, true, true, - true, true, true, - true, true, true, - true}; + Expanded.BraceWrapping = { + /*AfterCaseLabel=*/true, + /*AfterClass=*/true, + /*AfterControlStatement=*/FormatStyle::BWACS_Always, + /*AfterEnum=*/true, + /*AfterFunction=*/true, + /*AfterNamespace=*/true, + /*AfterObjCDeclaration=*/true, + /*AfterStruct=*/true, + /*AfterUnion=*/true, + /*AfterExternBlock=*/true, + /*BeforeCatch=*/true, + /*BeforeElse=*/true, + /*BeforeLambdaBody=*/false, + /*BeforeWhile=*/true, + /*IndentBraces=*/true, + /*SplitEmptyFunction=*/true, + /*SplitEmptyRecord=*/true, + /*SplitEmptyNamespace=*/true}; + Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock; break; case FormatStyle::BS_WebKit: Expanded.BraceWrapping.AfterFunction = true; @@ -728,14 +810,16 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { LLVMStyle.AccessModifierOffset = -2; LLVMStyle.AlignEscapedNewlines = FormatStyle::ENAS_Right; LLVMStyle.AlignAfterOpenBracket = FormatStyle::BAS_Align; - LLVMStyle.AlignOperands = true; + LLVMStyle.AlignOperands = FormatStyle::OAS_Align; LLVMStyle.AlignTrailingComments = true; LLVMStyle.AlignConsecutiveAssignments = false; + LLVMStyle.AlignConsecutiveBitFields = false; LLVMStyle.AlignConsecutiveDeclarations = false; LLVMStyle.AlignConsecutiveMacros = false; LLVMStyle.AllowAllArgumentsOnNextLine = true; LLVMStyle.AllowAllConstructorInitializersOnNextLine = true; LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true; + LLVMStyle.AllowShortEnumsOnASingleLine = true; LLVMStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All; LLVMStyle.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Never; LLVMStyle.AllowShortCaseLabelsOnASingleLine = false; @@ -751,12 +835,25 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { LLVMStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_None; LLVMStyle.BreakBeforeTernaryOperators = true; LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach; - LLVMStyle.BraceWrapping = {false, false, FormatStyle::BWACS_Never, - false, false, false, - false, false, false, - false, false, false, - false, true, true, - true}; + LLVMStyle.BraceWrapping = {/*AfterCaseLabel=*/false, + /*AfterClass=*/false, + /*AfterControlStatement=*/FormatStyle::BWACS_Never, + /*AfterEnum=*/false, + /*AfterFunction=*/false, + /*AfterNamespace=*/false, + /*AfterObjCDeclaration=*/false, + /*AfterStruct=*/false, + /*AfterUnion=*/false, + /*AfterExternBlock=*/false, + /*BeforeCatch=*/false, + /*BeforeElse=*/false, + /*BeforeLambdaBody=*/false, + /*BeforeWhile=*/false, + /*IndentBraces=*/false, + /*SplitEmptyFunction=*/true, + /*SplitEmptyRecord=*/true, + /*SplitEmptyNamespace=*/true}; + LLVMStyle.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock; LLVMStyle.BreakAfterJavaFieldAnnotations = false; LLVMStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon; LLVMStyle.BreakInheritanceList = FormatStyle::BILS_BeforeColon; @@ -782,10 +879,12 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { LLVMStyle.IncludeStyle.IncludeIsMainRegex = "(Test)?$"; LLVMStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Preserve; LLVMStyle.IndentCaseLabels = false; + LLVMStyle.IndentCaseBlocks = false; LLVMStyle.IndentGotoLabels = true; LLVMStyle.IndentPPDirectives = FormatStyle::PPDIS_None; LLVMStyle.IndentWrappedFunctionNames = false; LLVMStyle.IndentWidth = 2; + LLVMStyle.InsertTrailingCommas = FormatStyle::TCS_None; LLVMStyle.JavaScriptQuotes = FormatStyle::JSQS_Leave; LLVMStyle.JavaScriptWrapImports = true; LLVMStyle.TabWidth = 8; @@ -794,6 +893,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { LLVMStyle.NamespaceIndentation = FormatStyle::NI_None; LLVMStyle.ObjCBinPackProtocolList = FormatStyle::BPS_Auto; LLVMStyle.ObjCBlockIndentWidth = 2; + LLVMStyle.ObjCBreakBeforeNestedBlockParam = true; LLVMStyle.ObjCSpaceAfterProperty = false; LLVMStyle.ObjCSpaceBeforeProtocolList = true; LLVMStyle.PointerAlignment = FormatStyle::PAS_Right; @@ -835,6 +935,9 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { LLVMStyle.SortUsingDeclarations = true; LLVMStyle.StatementMacros.push_back("Q_UNUSED"); LLVMStyle.StatementMacros.push_back("QT_REQUIRE_VERSION"); + LLVMStyle.WhitespaceSensitiveMacros.push_back("STRINGIZE"); + LLVMStyle.WhitespaceSensitiveMacros.push_back("PP_STRINGIZE"); + LLVMStyle.WhitespaceSensitiveMacros.push_back("BOOST_PP_STRINGIZE"); // Defaults that differ when not C++. if (Language == FormatStyle::LK_TableGen) { @@ -911,6 +1014,8 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) { "PARSE_TEXT_PROTO", "ParseTextOrDie", "ParseTextProtoOrDie", + "ParseTestProto", + "ParsePartialTestProto", }, /*CanonicalDelimiter=*/"", /*BasedOnStyle=*/"google", @@ -924,7 +1029,7 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) { if (Language == FormatStyle::LK_Java) { GoogleStyle.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; - GoogleStyle.AlignOperands = false; + GoogleStyle.AlignOperands = FormatStyle::OAS_DontAlign; GoogleStyle.AlignTrailingComments = false; GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty; GoogleStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never; @@ -935,13 +1040,18 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) { GoogleStyle.SpacesBeforeTrailingComments = 1; } else if (Language == FormatStyle::LK_JavaScript) { GoogleStyle.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; - GoogleStyle.AlignOperands = false; + GoogleStyle.AlignOperands = FormatStyle::OAS_DontAlign; GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty; + // TODO: still under discussion whether to switch to SLS_All. + GoogleStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_Empty; GoogleStyle.AlwaysBreakBeforeMultilineStrings = false; GoogleStyle.BreakBeforeTernaryOperators = false; - // taze:, triple slash directives (`/// <...`), @see, which is commonly - // followed by overlong URLs. - GoogleStyle.CommentPragmas = "(taze:|^/[ \t]*<|@see)"; + // taze:, triple slash directives (`/// <...`), tslint:, and @see, which is + // commonly followed by overlong URLs. + GoogleStyle.CommentPragmas = "(taze:|^/[ \t]*<|tslint:|@see)"; + // TODO: enable once decided, in particular re disabling bin packing. + // https://google.github.io/styleguide/jsguide.html#features-arrays-trailing-comma + // GoogleStyle.InsertTrailingCommas = FormatStyle::TCS_Wrapped; GoogleStyle.MaxEmptyLinesToKeep = 3; GoogleStyle.NamespaceIndentation = FormatStyle::NI_All; GoogleStyle.SpacesInContainerLiterals = false; @@ -966,6 +1076,12 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) { // #imports, etc.) GoogleStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Preserve; + } else if (Language == FormatStyle::LK_CSharp) { + GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty; + GoogleStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never; + GoogleStyle.BreakStringLiterals = false; + GoogleStyle.ColumnLimit = 100; + GoogleStyle.NamespaceIndentation = FormatStyle::NI_All; } return GoogleStyle; @@ -1061,7 +1177,7 @@ FormatStyle getWebKitStyle() { FormatStyle Style = getLLVMStyle(); Style.AccessModifierOffset = -4; Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; - Style.AlignOperands = false; + Style.AlignOperands = FormatStyle::OAS_DontAlign; Style.AlignTrailingComments = false; Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Empty; Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All; @@ -1110,9 +1226,12 @@ FormatStyle getMicrosoftStyle(FormatStyle::LanguageKind Language) { Style.BraceWrapping.AfterObjCDeclaration = true; Style.BraceWrapping.AfterStruct = true; Style.BraceWrapping.AfterExternBlock = true; + Style.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock; Style.BraceWrapping.BeforeCatch = true; Style.BraceWrapping.BeforeElse = true; + Style.BraceWrapping.BeforeWhile = false; Style.PenaltyReturnTypeOnItsOwnLine = 1000; + Style.AllowShortEnumsOnASingleLine = false; Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None; Style.AllowShortCaseLabelsOnASingleLine = false; Style.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never; @@ -1207,6 +1326,11 @@ std::error_code parseConfiguration(StringRef Text, FormatStyle *Style) { StyleSet.Add(std::move(DefaultStyle)); } *Style = *StyleSet.Get(Language); + if (Style->InsertTrailingCommas != FormatStyle::TCS_None && + Style->BinPackArguments) { + // See comment on FormatStyle::TSC_Wrapped. + return make_error_code(ParseError::BinPackTrailingCommaConflict); + } return make_error_code(ParseError::Success); } @@ -1462,6 +1586,75 @@ private: FormattingAttemptStatus *Status; }; +/// TrailingCommaInserter inserts trailing commas into container literals. +/// E.g.: +/// const x = [ +/// 1, +/// ]; +/// TrailingCommaInserter runs after formatting. To avoid causing a required +/// reformatting (and thus reflow), it never inserts a comma that'd exceed the +/// ColumnLimit. +/// +/// Because trailing commas disable binpacking of arrays, TrailingCommaInserter +/// is conceptually incompatible with bin packing. +class TrailingCommaInserter : public TokenAnalyzer { +public: + TrailingCommaInserter(const Environment &Env, const FormatStyle &Style) + : TokenAnalyzer(Env, Style) {} + + std::pair<tooling::Replacements, unsigned> + analyze(TokenAnnotator &Annotator, + SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, + FormatTokenLexer &Tokens) override { + AffectedRangeMgr.computeAffectedLines(AnnotatedLines); + tooling::Replacements Result; + insertTrailingCommas(AnnotatedLines, Result); + return {Result, 0}; + } + +private: + /// Inserts trailing commas in [] and {} initializers if they wrap over + /// multiple lines. + void insertTrailingCommas(SmallVectorImpl<AnnotatedLine *> &Lines, + tooling::Replacements &Result) { + for (AnnotatedLine *Line : Lines) { + insertTrailingCommas(Line->Children, Result); + if (!Line->Affected) + continue; + for (FormatToken *FormatTok = Line->First; FormatTok; + FormatTok = FormatTok->Next) { + if (FormatTok->NewlinesBefore == 0) + continue; + FormatToken *Matching = FormatTok->MatchingParen; + if (!Matching || !FormatTok->getPreviousNonComment()) + continue; + if (!(FormatTok->is(tok::r_square) && + Matching->is(TT_ArrayInitializerLSquare)) && + !(FormatTok->is(tok::r_brace) && Matching->is(TT_DictLiteral))) + continue; + FormatToken *Prev = FormatTok->getPreviousNonComment(); + if (Prev->is(tok::comma) || Prev->is(tok::semi)) + continue; + // getEndLoc is not reliably set during re-lexing, use text length + // instead. + SourceLocation Start = + Prev->Tok.getLocation().getLocWithOffset(Prev->TokenText.size()); + // If inserting a comma would push the code over the column limit, skip + // this location - it'd introduce an unstable formatting due to the + // required reflow. + unsigned ColumnNumber = + Env.getSourceManager().getSpellingColumnNumber(Start); + if (ColumnNumber > Style.ColumnLimit) + continue; + // Comma insertions cannot conflict with each other, and this pass has a + // clean set of Replacements, so the operation below cannot fail. + cantFail(Result.add( + tooling::Replacement(Env.getSourceManager(), Start, 0, ","))); + } + } + } +}; + // This class clean up the erroneous/redundant code around the given ranges in // file. class Cleaner : public TokenAnalyzer { @@ -1808,7 +2001,7 @@ private: << FormatTok->Tok.getLocation().printToString( SourceManager) << " token: " << FormatTok->TokenText << " token type: " - << getTokenTypeName(FormatTok->Type) << "\n"); + << getTokenTypeName(FormatTok->getType()) << "\n"); return true; } if (guessIsObjC(SourceManager, Line->Children, Keywords)) @@ -1951,8 +2144,7 @@ static void sortCppIncludes(const FormatStyle &Style, // enough as additional newlines might be added or removed across #include // blocks. This we handle below by generating the updated #imclude blocks and // comparing it to the original. - if (Indices.size() == Includes.size() && - std::is_sorted(Indices.begin(), Indices.end()) && + if (Indices.size() == Includes.size() && llvm::is_sorted(Indices) && Style.IncludeStyle.IncludeBlocks == tooling::IncludeStyle::IBS_Preserve) return; @@ -1973,8 +2165,8 @@ static void sortCppIncludes(const FormatStyle &Style, // If the #includes are out of order, we generate a single replacement fixing // the entire range of blocks. Otherwise, no replacement is generated. - if (replaceCRLF(result) == - replaceCRLF(Code.substr(IncludesBeginOffset, IncludesBlockSize))) + if (replaceCRLF(result) == replaceCRLF(std::string(Code.substr( + IncludesBeginOffset, IncludesBlockSize)))) return; auto Err = Replaces.add(tooling::Replacement( @@ -2142,8 +2334,8 @@ static void sortJavaImports(const FormatStyle &Style, // If the imports are out of order, we generate a single replacement fixing // the entire block. Otherwise, no replacement is generated. - if (replaceCRLF(result) == - replaceCRLF(Code.substr(Imports.front().Offset, ImportsBlockSize))) + if (replaceCRLF(result) == replaceCRLF(std::string(Code.substr( + Imports.front().Offset, ImportsBlockSize)))) return; auto Err = Replaces.add(tooling::Replacement(FileName, Imports.front().Offset, @@ -2431,6 +2623,12 @@ reformat(const FormatStyle &Style, StringRef Code, return Formatter(Env, Expanded, Status).process(); }); + if (Style.Language == FormatStyle::LK_JavaScript && + Style.InsertTrailingCommas == FormatStyle::TCS_Wrapped) + Passes.emplace_back([&](const Environment &Env) { + return TrailingCommaInserter(Env, Expanded).process(); + }); + auto Env = std::make_unique<Environment>(Code, FileName, Ranges, FirstStartColumn, NextStartColumn, LastStartColumn); @@ -2518,7 +2716,8 @@ LangOptions getFormattingLangOpts(const FormatStyle &Style) { LangOpts.CPlusPlus11 = LexingStd >= FormatStyle::LS_Cpp11; LangOpts.CPlusPlus14 = LexingStd >= FormatStyle::LS_Cpp14; LangOpts.CPlusPlus17 = LexingStd >= FormatStyle::LS_Cpp17; - LangOpts.CPlusPlus2a = LexingStd >= FormatStyle::LS_Cpp20; + LangOpts.CPlusPlus20 = LexingStd >= FormatStyle::LS_Cpp20; + LangOpts.Char8 = LexingStd >= FormatStyle::LS_Cpp20; LangOpts.LineComment = 1; bool AlternativeOperators = Style.isCpp(); @@ -2532,7 +2731,7 @@ LangOptions getFormattingLangOpts(const FormatStyle &Style) { const char *StyleOptionHelpDescription = "Coding style, currently supports:\n" - " LLVM, Google, Chromium, Mozilla, WebKit.\n" + " LLVM, GNU, Google, Chromium, Microsoft, Mozilla, WebKit.\n" "Use -style=file to load style configuration from\n" ".clang-format file located in one of the parent\n" "directories of the source file (or current\n" |