[clang] 358eaa3 - [clang-format] Flexible line endings
Cameron Desrochers via cfe-commits
cfe-commits at lists.llvm.org
Fri Nov 15 08:50:58 PST 2019
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) {
More information about the cfe-commits
mailing list