Author: benhamilton Date: Wed Feb 21 07:54:31 2018 New Revision: 325691 URL: http://llvm.org/viewvc/llvm-project?rev=325691&view=rev Log: [clang-format] New API guessLanguage()
Summary: For clients which don't have a filesystem, calling getStyle() doesn't make much sense (there's no .clang-format files to search for). In this diff, I hoist out the language-guessing logic from getStyle() and move it into a new API guessLanguage(). I also added support for guessing the language of files which have no extension (they could be C++ or ObjC). Test Plan: New tests added. Ran tests with: % make -j12 FormatTests && ./tools/clang/unittests/Format/FormatTests Reviewers: jolesiak, krasimir Reviewed By: jolesiak, krasimir Subscribers: klimek, cfe-commits, sammccall Differential Revision: https://reviews.llvm.org/D43522 Modified: cfe/trunk/include/clang/Format/Format.h cfe/trunk/lib/Format/Format.cpp cfe/trunk/unittests/Format/FormatTest.cpp Modified: cfe/trunk/include/clang/Format/Format.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Format/Format.h?rev=325691&r1=325690&r2=325691&view=diff ============================================================================== --- cfe/trunk/include/clang/Format/Format.h (original) +++ cfe/trunk/include/clang/Format/Format.h Wed Feb 21 07:54:31 2018 @@ -1981,6 +1981,10 @@ llvm::Expected<FormatStyle> getStyle(Str StringRef Code = "", vfs::FileSystem *FS = nullptr); +// \brief Guesses the language from the ``FileName`` and ``Code`` to be formatted. +// Defaults to FormatStyle::LK_Cpp. +FormatStyle::LanguageKind guessLanguage(StringRef FileName, StringRef Code); + // \brief Returns a string representation of ``Language``. inline StringRef getLanguageName(FormatStyle::LanguageKind Language) { switch (Language) { Modified: cfe/trunk/lib/Format/Format.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=325691&r1=325690&r2=325691&view=diff ============================================================================== --- cfe/trunk/lib/Format/Format.cpp (original) +++ cfe/trunk/lib/Format/Format.cpp Wed Feb 21 07:54:31 2018 @@ -2294,6 +2294,25 @@ static FormatStyle::LanguageKind getLang return FormatStyle::LK_Cpp; } +FormatStyle::LanguageKind guessLanguage(StringRef FileName, StringRef Code) { + FormatStyle::LanguageKind result = getLanguageByFileName(FileName); + if (result == FormatStyle::LK_Cpp) { + auto extension = llvm::sys::path::extension(FileName); + // If there's no file extension (or it's .h), we need to check the contents + // of the code to see if it contains Objective-C. + if (extension.empty() || extension == ".h") { + std::unique_ptr<Environment> Env = + Environment::CreateVirtualEnvironment(Code, FileName, /*Ranges=*/{}); + ObjCHeaderStyleGuesser Guesser(*Env, getLLVMStyle()); + Guesser.process(); + if (Guesser.isObjC()) { + result = FormatStyle::LK_ObjC; + } + } + } + return result; +} + llvm::Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName, StringRef FallbackStyleName, StringRef Code, vfs::FileSystem *FS) { @@ -2301,17 +2320,7 @@ llvm::Expected<FormatStyle> getStyle(Str FS = vfs::getRealFileSystem().get(); } FormatStyle Style = getLLVMStyle(); - Style.Language = getLanguageByFileName(FileName); - - if (Style.Language == FormatStyle::LK_Cpp && FileName.endswith(".h")) { - std::unique_ptr<Environment> Env = - Environment::CreateVirtualEnvironment(Code, FileName, /*Ranges=*/{}); - ObjCHeaderStyleGuesser Guesser(*Env, Style); - Guesser.process(); - if (Guesser.isObjC()) { - Style.Language = FormatStyle::LK_ObjC; - } - } + Style.Language = guessLanguage(FileName, Code); FormatStyle FallbackStyle = getNoStyle(); if (!getPredefinedStyle(FallbackStyleName, Style.Language, &FallbackStyle)) Modified: cfe/trunk/unittests/Format/FormatTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=325691&r1=325690&r2=325691&view=diff ============================================================================== --- cfe/trunk/unittests/Format/FormatTest.cpp (original) +++ cfe/trunk/unittests/Format/FormatTest.cpp Wed Feb 21 07:54:31 2018 @@ -11952,6 +11952,34 @@ TEST_F(FormatTest, StructuredBindings) { verifyFormat("auto const &[ a, b ] = f();", Spaces); } +struct GuessLanguageTestCase { + const char *const FileName; + const char *const Code; + const FormatStyle::LanguageKind ExpectedResult; +}; + +class GuessLanguageTest + : public FormatTest, + public ::testing::WithParamInterface<GuessLanguageTestCase> {}; + +TEST_P(GuessLanguageTest, FileAndCode) { + auto TestCase = GetParam(); + EXPECT_EQ(TestCase.ExpectedResult, + guessLanguage(TestCase.FileName, TestCase.Code)); +} + +static const GuessLanguageTestCase TestCases[] = { + {"foo.cc", "", FormatStyle::LK_Cpp}, + {"foo.m", "", FormatStyle::LK_ObjC}, + {"foo.mm", "", FormatStyle::LK_ObjC}, + {"foo.h", "", FormatStyle::LK_Cpp}, + {"foo.h", "@interface Foo\n@end\n", FormatStyle::LK_ObjC}, + {"foo", "", FormatStyle::LK_Cpp}, + {"foo", "@interface Foo\n@end\n", FormatStyle::LK_ObjC}, +}; +INSTANTIATE_TEST_CASE_P(ValidLanguages, GuessLanguageTest, + ::testing::ValuesIn(TestCases)); + } // end namespace } // end namespace format } // end namespace clang _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits