Author: Cameron Desrochers Date: 2019-11-15T11:50:22-05:00 New Revision: 358eaa3dcea1dee6350c2cbf80aab3c25db4d4d9
URL: https://github.com/llvm/llvm-project/commit/358eaa3dcea1dee6350c2cbf80aab3c25db4d4d9 DIFF: https://github.com/llvm/llvm-project/commit/358eaa3dcea1dee6350c2cbf80aab3c25db4d4d9.diff LOG: [clang-format] Flexible line endings Line ending detection is now set with the `DeriveLineEnding` option. CRLF can now be used as the default line ending by setting `UseCRLF`. When line ending detection is disabled, all line endings are converted according to the `UseCRLF` option. Differential Revision: https://reviews.llvm.org/D19031 Added: Modified: clang/include/clang/Format/Format.h clang/lib/Format/Format.cpp clang/unittests/Format/FormatTest.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 329579bea3d4..f5c356fa2262 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -1217,6 +1217,10 @@ struct FormatStyle { /// \endcode bool Cpp11BracedListStyle; + /// \brief Analyze the formatted file for the most used line ending (``\r\n`` + /// or ``\n``). ``UseCRLF`` is only used as a fallback if none can be derived. + bool DeriveLineEnding; + /// If ``true``, analyze the formatted file for the most common /// alignment of ``&`` and ``*``. /// Pointer and reference alignment styles are going to be updated according @@ -2032,6 +2036,10 @@ struct FormatStyle { UT_Always }; + /// \brief Use ``\r\n`` instead of ``\n`` for line breaks. + /// Also used as fallback if ``DeriveLineEnding`` is true. + bool UseCRLF; + /// The way to use tab characters in the resulting file. UseTabStyle UseTab; @@ -2079,6 +2087,7 @@ struct FormatStyle { R.ConstructorInitializerIndentWidth && ContinuationIndentWidth == R.ContinuationIndentWidth && Cpp11BracedListStyle == R.Cpp11BracedListStyle && + DeriveLineEnding == R.DeriveLineEnding && DerivePointerAlignment == R.DerivePointerAlignment && DisableFormat == R.DisableFormat && ExperimentalAutoDetectBinPacking == @@ -2143,6 +2152,7 @@ struct FormatStyle { SpacesInSquareBrackets == R.SpacesInSquareBrackets && Standard == R.Standard && TabWidth == R.TabWidth && StatementMacros == R.StatementMacros && UseTab == R.UseTab && + UseCRLF == R.UseCRLF && TypenameMacros == R.TypenameMacros; } diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 60958597ad21..083c3a8f02fd 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -467,6 +467,7 @@ template <> struct MappingTraits<FormatStyle> { Style.ConstructorInitializerIndentWidth); IO.mapOptional("ContinuationIndentWidth", Style.ContinuationIndentWidth); IO.mapOptional("Cpp11BracedListStyle", Style.Cpp11BracedListStyle); + IO.mapOptional("DeriveLineEnding", Style.DeriveLineEnding); IO.mapOptional("DerivePointerAlignment", Style.DerivePointerAlignment); IO.mapOptional("DisableFormat", Style.DisableFormat); IO.mapOptional("ExperimentalAutoDetectBinPacking", @@ -546,6 +547,7 @@ template <> struct MappingTraits<FormatStyle> { IO.mapOptional("StatementMacros", Style.StatementMacros); IO.mapOptional("TabWidth", Style.TabWidth); IO.mapOptional("TypenameMacros", Style.TypenameMacros); + IO.mapOptional("UseCRLF", Style.UseCRLF); IO.mapOptional("UseTab", Style.UseTab); } }; @@ -762,6 +764,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { LLVMStyle.ConstructorInitializerIndentWidth = 4; LLVMStyle.ContinuationIndentWidth = 4; LLVMStyle.Cpp11BracedListStyle = true; + LLVMStyle.DeriveLineEnding = true; LLVMStyle.DerivePointerAlignment = false; LLVMStyle.ExperimentalAutoDetectBinPacking = false; LLVMStyle.FixNamespaceComments = true; @@ -792,6 +795,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { LLVMStyle.PointerAlignment = FormatStyle::PAS_Right; LLVMStyle.SpacesBeforeTrailingComments = 1; LLVMStyle.Standard = FormatStyle::LS_Latest; + LLVMStyle.UseCRLF = false; LLVMStyle.UseTab = FormatStyle::UT_Never; LLVMStyle.ReflowComments = true; LLVMStyle.SpacesInParentheses = false; @@ -1350,7 +1354,10 @@ class Formatter : public TokenAnalyzer { WhitespaceManager Whitespaces( Env.getSourceManager(), Style, - inputUsesCRLF(Env.getSourceManager().getBufferData(Env.getFileID()))); + Style.DeriveLineEnding ? + inputUsesCRLF(Env.getSourceManager().getBufferData(Env.getFileID()), + Style.UseCRLF) : + Style.UseCRLF); ContinuationIndenter Indenter(Style, Tokens.getKeywords(), Env.getSourceManager(), Whitespaces, Encoding, BinPackInconclusiveFunctions); @@ -1371,8 +1378,10 @@ class Formatter : public TokenAnalyzer { } private: - static bool inputUsesCRLF(StringRef Text) { - return Text.count('\r') * 2 > Text.count('\n'); + static bool inputUsesCRLF(StringRef Text, bool DefaultToCRLF) { + size_t LF = Text.count('\n'); + size_t CR = Text.count('\r') * 2; + return LF == CR ? DefaultToCRLF : CR > LF; } bool diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index b8a73621c779..122c59782b66 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -12500,6 +12500,7 @@ TEST_F(FormatTest, ParsesConfigurationBools) { CHECK_PARSE_BOOL(BreakStringLiterals); CHECK_PARSE_BOOL(CompactNamespaces); CHECK_PARSE_BOOL(ConstructorInitializerAllOnOneLineOrOnePerLine); + CHECK_PARSE_BOOL(DeriveLineEnding); CHECK_PARSE_BOOL(DerivePointerAlignment); CHECK_PARSE_BOOL_FIELD(DerivePointerAlignment, "DerivePointerBinding"); CHECK_PARSE_BOOL(DisableFormat); @@ -12528,6 +12529,7 @@ TEST_F(FormatTest, ParsesConfigurationBools) { CHECK_PARSE_BOOL(SpaceBeforeCtorInitializerColon); CHECK_PARSE_BOOL(SpaceBeforeInheritanceColon); CHECK_PARSE_BOOL(SpaceBeforeRangeBasedForLoopColon); + CHECK_PARSE_BOOL(UseCRLF); CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterCaseLabel); CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterClass); @@ -14056,6 +14058,94 @@ TEST_F(FormatTest, SupportsCRLF) { format("/*\r\n" " \r\r\r\n" "*/")); + + FormatStyle style = getLLVMStyle(); + + style.DeriveLineEnding = true; + style.UseCRLF = false; + EXPECT_EQ("union FooBarBazQux {\n" + " int foo;\n" + " int bar;\n" + " int baz;\n" + "};", + format("union FooBarBazQux {\r\n" + " int foo;\n" + " int bar;\r\n" + " int baz;\n" + "};", + style)); + style.UseCRLF = true; + EXPECT_EQ("union FooBarBazQux {\r\n" + " int foo;\r\n" + " int bar;\r\n" + " int baz;\r\n" + "};", + format("union FooBarBazQux {\r\n" + " int foo;\n" + " int bar;\r\n" + " int baz;\n" + "};", + style)); + + style.DeriveLineEnding = false; + style.UseCRLF = false; + EXPECT_EQ("union FooBarBazQux {\n" + " int foo;\n" + " int bar;\n" + " int baz;\n" + " int qux;\n" + "};", + format("union FooBarBazQux {\r\n" + " int foo;\n" + " int bar;\r\n" + " int baz;\n" + " int qux;\r\n" + "};", + style)); + style.UseCRLF = true; + EXPECT_EQ("union FooBarBazQux {\r\n" + " int foo;\r\n" + " int bar;\r\n" + " int baz;\r\n" + " int qux;\r\n" + "};", + format("union FooBarBazQux {\r\n" + " int foo;\n" + " int bar;\r\n" + " int baz;\n" + " int qux;\n" + "};", + style)); + + style.DeriveLineEnding = true; + style.UseCRLF = false; + EXPECT_EQ("union FooBarBazQux {\r\n" + " int foo;\r\n" + " int bar;\r\n" + " int baz;\r\n" + " int qux;\r\n" + "};", + format("union FooBarBazQux {\r\n" + " int foo;\n" + " int bar;\r\n" + " int baz;\n" + " int qux;\r\n" + "};", + style)); + style.UseCRLF = true; + EXPECT_EQ("union FooBarBazQux {\n" + " int foo;\n" + " int bar;\n" + " int baz;\n" + " int qux;\n" + "};", + format("union FooBarBazQux {\r\n" + " int foo;\n" + " int bar;\r\n" + " int baz;\n" + " int qux;\n" + "};", + style)); } TEST_F(FormatTest, MunchSemicolonAfterBlocks) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits