Author: djasper Date: Mon Mar 21 09:11:27 2016 New Revision: 263943 URL: http://llvm.org/viewvc/llvm-project?rev=263943&view=rev Log: clang-format: Make include sorting's main include detection configurable.
This patch adds a regular expression to configure suffixes of an included file to check whether it is the "main" include of the current file. Previously, clang-format has allowed arbitrary suffixes on the formatted file, which is still the case when no IncludeMainRegex is specified. Modified: cfe/trunk/docs/ClangFormatStyleOptions.rst cfe/trunk/include/clang/Format/Format.h cfe/trunk/lib/Format/Format.cpp cfe/trunk/unittests/Format/FormatTest.cpp cfe/trunk/unittests/Format/SortIncludesTest.cpp Modified: cfe/trunk/docs/ClangFormatStyleOptions.rst URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ClangFormatStyleOptions.rst?rev=263943&r1=263942&r2=263943&view=diff ============================================================================== --- cfe/trunk/docs/ClangFormatStyleOptions.rst (original) +++ cfe/trunk/docs/ClangFormatStyleOptions.rst Mon Mar 21 09:11:27 2016 @@ -519,6 +519,19 @@ the configuration (without a prefix: ``A - Regex: '.\*' Priority: 1 +**IncludeIsMainRegex** (``std::string``) + Specify a regular expression of suffixes that are allowed in the + file-to-main-include mapping. + + When guessing whether a #include is the "main" include (to assign + category 0, see above), use this regex of allowed suffixes to the header + stem. A partial match is done, so that: + - "" means "arbitrary suffix" + - "$" means "no suffix" + + For example, if configured to "(_test)?$", then a header a.h would be seen + as the "main" include in both a.cc and a_test.cc. + **IndentCaseLabels** (``bool``) Indent case labels one level from the switch statement. @@ -532,6 +545,22 @@ the configuration (without a prefix: ``A Indent if a function definition or declaration is wrapped after the type. +**JavaScriptQuotes** (``JavaScriptQuoteStyle``) + The JavaScriptQuoteStyle to use for JavaScript strings. + + Possible values: + + * ``JSQS_Leave`` (in configuration: ``Leave``) + Leave string quotes as they are. + + * ``JSQS_Single`` (in configuration: ``Single``) + Always use single quotes. + + * ``JSQS_Double`` (in configuration: ``Double``) + Always use double quotes. + + + **KeepEmptyLinesAtTheStartOfBlocks** (``bool``) If true, empty lines at the start of blocks are kept. Modified: cfe/trunk/include/clang/Format/Format.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Format/Format.h?rev=263943&r1=263942&r2=263943&view=diff ============================================================================== --- cfe/trunk/include/clang/Format/Format.h (original) +++ cfe/trunk/include/clang/Format/Format.h Mon Mar 21 09:11:27 2016 @@ -401,6 +401,19 @@ struct FormatStyle { /// \endcode std::vector<IncludeCategory> IncludeCategories; + /// \brief Specify a regular expression of suffixes that are allowed in the + /// file-to-main-include mapping. + /// + /// When guessing whether a #include is the "main" include (to assign + /// category 0, see above), use this regex of allowed suffixes to the header + /// stem. A partial match is done, so that: + /// - "" means "arbitrary suffix" + /// - "$" means "no suffix" + /// + /// For example, if configured to "(_test)?$", then a header a.h would be seen + /// as the "main" include in both a.cc and a_test.cc. + std::string IncludeIsMainRegex; + /// \brief Indent case labels one level from the switch statement. /// /// When ``false``, use the same indentation level as for the switch statement. Modified: cfe/trunk/lib/Format/Format.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=263943&r1=263942&r2=263943&view=diff ============================================================================== --- cfe/trunk/lib/Format/Format.cpp (original) +++ cfe/trunk/lib/Format/Format.cpp Mon Mar 21 09:11:27 2016 @@ -300,6 +300,7 @@ template <> struct MappingTraits<FormatS Style.ExperimentalAutoDetectBinPacking); IO.mapOptional("ForEachMacros", Style.ForEachMacros); IO.mapOptional("IncludeCategories", Style.IncludeCategories); + IO.mapOptional("IncludeIsMainRegex", Style.IncludeIsMainRegex); IO.mapOptional("IndentCaseLabels", Style.IndentCaseLabels); IO.mapOptional("IndentWidth", Style.IndentWidth); IO.mapOptional("IndentWrappedFunctionNames", @@ -517,6 +518,7 @@ FormatStyle getLLVMStyle() { LLVMStyle.IncludeCategories = {{"^\"(llvm|llvm-c|clang|clang-c)/", 2}, {"^(<|\"(gtest|isl|json)/)", 3}, {".*", 1}}; + LLVMStyle.IncludeIsMainRegex = "$"; LLVMStyle.IndentCaseLabels = false; LLVMStyle.IndentWrappedFunctionNames = false; LLVMStyle.IndentWidth = 2; @@ -569,6 +571,7 @@ FormatStyle getGoogleStyle(FormatStyle:: GoogleStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = true; GoogleStyle.DerivePointerAlignment = true; GoogleStyle.IncludeCategories = {{"^<.*\\.h>", 1}, {"^<.*", 2}, {".*", 3}}; + GoogleStyle.IncludeIsMainRegex = "([-_](test|unittest))?$"; GoogleStyle.IndentCaseLabels = true; GoogleStyle.KeepEmptyLinesAtTheStartOfBlocks = false; GoogleStyle.ObjCSpaceAfterProperty = false; @@ -1961,8 +1964,12 @@ tooling::Replacements sortIncludes(const StringRef HeaderStem = llvm::sys::path::stem(IncludeName.drop_front(1).drop_back(1)); if (FileStem.startswith(HeaderStem)) { - Category = 0; - MainIncludeFound = true; + llvm::Regex MainIncludeRegex( + (HeaderStem + Style.IncludeIsMainRegex).str()); + if (MainIncludeRegex.match(FileStem)) { + Category = 0; + MainIncludeFound = true; + } } } IncludesInBlock.push_back({IncludeName, Line, Prev, Category}); Modified: cfe/trunk/unittests/Format/FormatTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=263943&r1=263942&r2=263943&view=diff ============================================================================== --- cfe/trunk/unittests/Format/FormatTest.cpp (original) +++ cfe/trunk/unittests/Format/FormatTest.cpp Mon Mar 21 09:11:27 2016 @@ -9941,6 +9941,7 @@ TEST_F(FormatTest, ParsesConfiguration) SpacesBeforeTrailingComments, 1234u); CHECK_PARSE("IndentWidth: 32", IndentWidth, 32u); CHECK_PARSE("ContinuationIndentWidth: 11", ContinuationIndentWidth, 11u); + CHECK_PARSE("CommentPragmas: '// abc$'", CommentPragmas, "// abc$"); Style.PointerAlignment = FormatStyle::PAS_Middle; CHECK_PARSE("PointerAlignment: Left", PointerAlignment, @@ -10099,6 +10100,7 @@ TEST_F(FormatTest, ParsesConfiguration) " - Regex: .*\n" " Priority: 1", IncludeCategories, ExpectedCategories); + CHECK_PARSE("IncludeIsMainRegex: 'abc$'", IncludeIsMainRegex, "abc$"); } TEST_F(FormatTest, ParsesConfigurationWithLanguages) { Modified: cfe/trunk/unittests/Format/SortIncludesTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/SortIncludesTest.cpp?rev=263943&r1=263942&r2=263943&view=diff ============================================================================== --- cfe/trunk/unittests/Format/SortIncludesTest.cpp (original) +++ cfe/trunk/unittests/Format/SortIncludesTest.cpp Mon Mar 21 09:11:27 2016 @@ -175,6 +175,7 @@ TEST_F(SortIncludesTest, HandlesMultilin } TEST_F(SortIncludesTest, LeavesMainHeaderFirst) { + Style.IncludeIsMainRegex = "([-_](test|unittest))?$"; EXPECT_EQ("#include \"llvm/a.h\"\n" "#include \"b.h\"\n" "#include \"c.h\"\n", @@ -188,7 +189,7 @@ TEST_F(SortIncludesTest, LeavesMainHeade sort("#include \"llvm/a.h\"\n" "#include \"c.h\"\n" "#include \"b.h\"\n", - "a_main.cc")); + "a_test.cc")); EXPECT_EQ("#include \"llvm/input.h\"\n" "#include \"b.h\"\n" "#include \"c.h\"\n", @@ -197,6 +198,24 @@ TEST_F(SortIncludesTest, LeavesMainHeade "#include \"b.h\"\n", "input.mm")); + // Don't allow prefixes. + EXPECT_EQ("#include \"b.h\"\n" + "#include \"c.h\"\n" + "#include \"llvm/not_a.h\"\n", + sort("#include \"llvm/not_a.h\"\n" + "#include \"c.h\"\n" + "#include \"b.h\"\n", + "a.cc")); + + // Don't do this for _main and other suffixes. + EXPECT_EQ("#include \"b.h\"\n" + "#include \"c.h\"\n" + "#include \"llvm/a.h\"\n", + sort("#include \"llvm/a.h\"\n" + "#include \"c.h\"\n" + "#include \"b.h\"\n", + "a_main.cc")); + // Don't do this in headers. EXPECT_EQ("#include \"b.h\"\n" "#include \"c.h\"\n" _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits