Allow predefined styles to define different options for different languages.
Summary:
Allow predefined styles to define different options for different
languages so that one can run:
clang-format -style=google file1.cpp file2.js
or use a single .clang-format file with "BasedOnStyle: Google" for both c++ and
JS files.
Added Google style for JavaScript with "BreakBeforeTernaryOperators" set to
false.
Reviewers: djasper
Reviewed By: djasper
CC: cfe-commits, klimek
Differential Revision: http://llvm-reviews.chandlerc.com/D2364
llvm-svn: 196909
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index faaafc2..562e67d 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -6950,42 +6950,88 @@
verifyFormat("#pragma omp reduction(+ : var)");
}
-bool allStylesEqual(ArrayRef<FormatStyle> Styles) {
- for (size_t i = 1; i < Styles.size(); ++i)
- if (!(Styles[0] == Styles[i]))
- return false;
- return true;
-}
+#define EXPECT_ALL_STYLES_EQUAL(Styles) \
+ for (size_t i = 1; i < Styles.size(); ++i) \
+ EXPECT_EQ(Styles[0], Styles[i]) << "Style #" << i << " of " \
+ << Styles.size() \
+ << " differs from Style #0"
TEST_F(FormatTest, GetsPredefinedStyleByName) {
- FormatStyle Styles[3];
+ SmallVector<FormatStyle, 3> Styles;
+ Styles.resize(3);
Styles[0] = getLLVMStyle();
- EXPECT_TRUE(getPredefinedStyle("LLVM", &Styles[1]));
- EXPECT_TRUE(getPredefinedStyle("lLvM", &Styles[2]));
- EXPECT_TRUE(allStylesEqual(Styles));
+ EXPECT_TRUE(getPredefinedStyle("LLVM", FormatStyle::LK_Cpp, &Styles[1]));
+ EXPECT_TRUE(getPredefinedStyle("lLvM", FormatStyle::LK_Cpp, &Styles[2]));
+ EXPECT_ALL_STYLES_EQUAL(Styles);
Styles[0] = getGoogleStyle();
- EXPECT_TRUE(getPredefinedStyle("Google", &Styles[1]));
- EXPECT_TRUE(getPredefinedStyle("gOOgle", &Styles[2]));
- EXPECT_TRUE(allStylesEqual(Styles));
+ EXPECT_TRUE(getPredefinedStyle("Google", FormatStyle::LK_Cpp, &Styles[1]));
+ EXPECT_TRUE(getPredefinedStyle("gOOgle", FormatStyle::LK_Cpp, &Styles[2]));
+ EXPECT_ALL_STYLES_EQUAL(Styles);
+
+ Styles[0] = getGoogleJSStyle();
+ EXPECT_TRUE(
+ getPredefinedStyle("Google", FormatStyle::LK_JavaScript, &Styles[1]));
+ EXPECT_TRUE(
+ getPredefinedStyle("gOOgle", FormatStyle::LK_JavaScript, &Styles[2]));
+ EXPECT_ALL_STYLES_EQUAL(Styles);
Styles[0] = getChromiumStyle();
- EXPECT_TRUE(getPredefinedStyle("Chromium", &Styles[1]));
- EXPECT_TRUE(getPredefinedStyle("cHRoMiUM", &Styles[2]));
- EXPECT_TRUE(allStylesEqual(Styles));
+ EXPECT_TRUE(getPredefinedStyle("Chromium", FormatStyle::LK_Cpp, &Styles[1]));
+ EXPECT_TRUE(getPredefinedStyle("cHRoMiUM", FormatStyle::LK_Cpp, &Styles[2]));
+ EXPECT_ALL_STYLES_EQUAL(Styles);
Styles[0] = getMozillaStyle();
- EXPECT_TRUE(getPredefinedStyle("Mozilla", &Styles[1]));
- EXPECT_TRUE(getPredefinedStyle("moZILla", &Styles[2]));
- EXPECT_TRUE(allStylesEqual(Styles));
+ EXPECT_TRUE(getPredefinedStyle("Mozilla", FormatStyle::LK_Cpp, &Styles[1]));
+ EXPECT_TRUE(getPredefinedStyle("moZILla", FormatStyle::LK_Cpp, &Styles[2]));
+ EXPECT_ALL_STYLES_EQUAL(Styles);
Styles[0] = getWebKitStyle();
- EXPECT_TRUE(getPredefinedStyle("WebKit", &Styles[1]));
- EXPECT_TRUE(getPredefinedStyle("wEbKit", &Styles[2]));
- EXPECT_TRUE(allStylesEqual(Styles));
+ EXPECT_TRUE(getPredefinedStyle("WebKit", FormatStyle::LK_Cpp, &Styles[1]));
+ EXPECT_TRUE(getPredefinedStyle("wEbKit", FormatStyle::LK_Cpp, &Styles[2]));
+ EXPECT_ALL_STYLES_EQUAL(Styles);
- EXPECT_FALSE(getPredefinedStyle("qwerty", &Styles[0]));
+ EXPECT_FALSE(getPredefinedStyle("qwerty", FormatStyle::LK_Cpp, &Styles[0]));
+}
+
+TEST_F(FormatTest, GetsCorrectBasedOnStyle) {
+ SmallVector<FormatStyle, 8> Styles;
+ Styles.resize(2);
+
+ Styles[0] = getGoogleStyle();
+ Styles[1] = getLLVMStyle();
+ EXPECT_EQ(0, parseConfiguration("BasedOnStyle: Google", &Styles[1]).value());
+ EXPECT_ALL_STYLES_EQUAL(Styles);
+
+ Styles.resize(5);
+ Styles[0] = getGoogleJSStyle();
+ Styles[1] = getLLVMStyle();
+ Styles[1].Language = FormatStyle::LK_JavaScript;
+ EXPECT_EQ(0, parseConfiguration("BasedOnStyle: Google", &Styles[1]).value());
+
+ Styles[2] = getLLVMStyle();
+ Styles[2].Language = FormatStyle::LK_JavaScript;
+ EXPECT_EQ(0, parseConfiguration("Language: JavaScript\n"
+ "BasedOnStyle: Google",
+ &Styles[2]).value());
+
+ Styles[3] = getLLVMStyle();
+ Styles[3].Language = FormatStyle::LK_JavaScript;
+ EXPECT_EQ(0, parseConfiguration("BasedOnStyle: Google\n"
+ "Language: JavaScript",
+ &Styles[3]).value());
+
+ Styles[4] = getLLVMStyle();
+ Styles[4].Language = FormatStyle::LK_JavaScript;
+ EXPECT_EQ(0, parseConfiguration("---\n"
+ "BasedOnStyle: LLVM\n"
+ "IndentWidth: 123\n"
+ "---\n"
+ "BasedOnStyle: Google\n"
+ "Language: JavaScript",
+ &Styles[4]).value());
+ EXPECT_ALL_STYLES_EQUAL(Styles);
}
#define CHECK_PARSE(TEXT, FIELD, VALUE) \
@@ -7192,6 +7238,23 @@
EXPECT_EQ(FormatStyle::LK_Cpp, Style.Language);
}
+TEST_F(FormatTest, UsesLanguageForBasedOnStyle) {
+ FormatStyle Style = {};
+ Style.Language = FormatStyle::LK_JavaScript;
+ Style.BreakBeforeTernaryOperators = true;
+ CHECK_PARSE("BasedOnStyle: Google", BreakBeforeTernaryOperators, false);
+ Style.BreakBeforeTernaryOperators = true;
+ CHECK_PARSE("---\n"
+ "BasedOnStyle: Google\n"
+ "---\n"
+ "Language: JavaScript\n"
+ "IndentWidth: 76\n"
+ "...\n",
+ BreakBeforeTernaryOperators, false);
+ EXPECT_EQ(76u, Style.IndentWidth);
+ EXPECT_EQ(FormatStyle::LK_JavaScript, Style.Language);
+}
+
#undef CHECK_PARSE
#undef CHECK_PARSE_BOOL
diff --git a/clang/unittests/Format/FormatTestJS.cpp b/clang/unittests/Format/FormatTestJS.cpp
index 1f8f139..0d242a7 100644
--- a/clang/unittests/Format/FormatTestJS.cpp
+++ b/clang/unittests/Format/FormatTestJS.cpp
@@ -33,24 +33,18 @@
}
static std::string format(llvm::StringRef Code,
- const FormatStyle &Style = getJSStyle()) {
+ const FormatStyle &Style = getGoogleJSStyle()) {
return format(Code, 0, Code.size(), Style);
}
- static FormatStyle getJSStyle() {
- FormatStyle Style = getLLVMStyle();
- Style.Language = FormatStyle::LK_JavaScript;
- return Style;
- }
-
- static FormatStyle getJSStyleWithColumns(unsigned ColumnLimit) {
- FormatStyle Style = getJSStyle();
+ static FormatStyle getGoogleJSStyleWithColumns(unsigned ColumnLimit) {
+ FormatStyle Style = getGoogleJSStyle();
Style.ColumnLimit = ColumnLimit;
return Style;
}
static void verifyFormat(llvm::StringRef Code,
- const FormatStyle &Style = getJSStyle()) {
+ const FormatStyle &Style = getGoogleJSStyle()) {
EXPECT_EQ(Code.str(), format(test::messUp(Code), Style));
}
};
@@ -60,26 +54,30 @@
verifyFormat("a != = b;");
verifyFormat("a === b;");
- verifyFormat("aaaaaaa ===\n b;", getJSStyleWithColumns(10));
+ verifyFormat("aaaaaaa ===\n b;", getGoogleJSStyleWithColumns(10));
verifyFormat("a !== b;");
- verifyFormat("aaaaaaa !==\n b;", getJSStyleWithColumns(10));
+ verifyFormat("aaaaaaa !==\n b;", getGoogleJSStyleWithColumns(10));
verifyFormat("if (a + b + c +\n"
" d !==\n"
" e + f + g)\n"
" q();",
- getJSStyleWithColumns(20));
+ getGoogleJSStyleWithColumns(20));
verifyFormat("a >> >= b;");
verifyFormat("a >>> b;");
- verifyFormat("aaaaaaa >>>\n b;", getJSStyleWithColumns(10));
+ verifyFormat("aaaaaaa >>>\n b;", getGoogleJSStyleWithColumns(10));
verifyFormat("a >>>= b;");
- verifyFormat("aaaaaaa >>>=\n b;", getJSStyleWithColumns(10));
+ verifyFormat("aaaaaaa >>>=\n b;", getGoogleJSStyleWithColumns(10));
verifyFormat("if (a + b + c +\n"
" d >>>\n"
" e + f + g)\n"
" q();",
- getJSStyleWithColumns(20));
+ getGoogleJSStyleWithColumns(20));
+ verifyFormat("var x = aaaaaaaaaa ?\n"
+ " bbbbbb :\n"
+ " ccc;",
+ getGoogleJSStyleWithColumns(20));
}
} // end namespace tooling