forked from OSchip/llvm-project
Added support for different VFSs in format::getStyle. Disable platform-related test case for MS compilers to avoid breaking buildbot.
llvm-svn: 264277
This commit is contained in:
parent
d47583232a
commit
547d87912a
|
@ -16,6 +16,7 @@
|
|||
#define LLVM_CLANG_FORMAT_FORMAT_H
|
||||
|
||||
#include "clang/Basic/LangOptions.h"
|
||||
#include "clang/Basic/VirtualFileSystem.h"
|
||||
#include "clang/Tooling/Core/Replacement.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include <system_error>
|
||||
|
@ -832,11 +833,13 @@ extern const char *StyleOptionHelpDescription;
|
|||
/// == "file".
|
||||
/// \param[in] FallbackStyle The name of a predefined style used to fallback to
|
||||
/// in case the style can't be determined from \p StyleName.
|
||||
/// \param[in] FS The underlying file system, in which the file resides. By
|
||||
/// default, the file system is the real file system.
|
||||
///
|
||||
/// \returns FormatStyle as specified by ``StyleName``. If no style could be
|
||||
/// determined, the default is LLVM Style (see ``getLLVMStyle()``).
|
||||
FormatStyle getStyle(StringRef StyleName, StringRef FileName,
|
||||
StringRef FallbackStyle);
|
||||
StringRef FallbackStyle, vfs::FileSystem *FS = nullptr);
|
||||
|
||||
} // end namespace format
|
||||
} // end namespace clang
|
||||
|
|
|
@ -2099,7 +2099,10 @@ static FormatStyle::LanguageKind getLanguageByFileName(StringRef FileName) {
|
|||
}
|
||||
|
||||
FormatStyle getStyle(StringRef StyleName, StringRef FileName,
|
||||
StringRef FallbackStyle) {
|
||||
StringRef FallbackStyle, vfs::FileSystem *FS) {
|
||||
if (!FS) {
|
||||
FS = vfs::getRealFileSystem().get();
|
||||
}
|
||||
FormatStyle Style = getLLVMStyle();
|
||||
Style.Language = getLanguageByFileName(FileName);
|
||||
if (!getPredefinedStyle(FallbackStyle, Style.Language, &Style)) {
|
||||
|
@ -2130,28 +2133,34 @@ FormatStyle getStyle(StringRef StyleName, StringRef FileName,
|
|||
llvm::sys::fs::make_absolute(Path);
|
||||
for (StringRef Directory = Path; !Directory.empty();
|
||||
Directory = llvm::sys::path::parent_path(Directory)) {
|
||||
if (!llvm::sys::fs::is_directory(Directory))
|
||||
|
||||
auto Status = FS->status(Directory);
|
||||
if (!Status ||
|
||||
Status->getType() != llvm::sys::fs::file_type::directory_file) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SmallString<128> ConfigFile(Directory);
|
||||
|
||||
llvm::sys::path::append(ConfigFile, ".clang-format");
|
||||
DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n");
|
||||
bool IsFile = false;
|
||||
// Ignore errors from is_regular_file: we only need to know if we can read
|
||||
// the file or not.
|
||||
llvm::sys::fs::is_regular_file(Twine(ConfigFile), IsFile);
|
||||
|
||||
Status = FS->status(ConfigFile.str());
|
||||
bool IsFile =
|
||||
Status && (Status->getType() == llvm::sys::fs::file_type::regular_file);
|
||||
if (!IsFile) {
|
||||
// Try _clang-format too, since dotfiles are not commonly used on Windows.
|
||||
ConfigFile = Directory;
|
||||
llvm::sys::path::append(ConfigFile, "_clang-format");
|
||||
DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n");
|
||||
llvm::sys::fs::is_regular_file(Twine(ConfigFile), IsFile);
|
||||
Status = FS->status(ConfigFile.str());
|
||||
IsFile = Status &&
|
||||
(Status->getType() == llvm::sys::fs::file_type::regular_file);
|
||||
}
|
||||
|
||||
if (IsFile) {
|
||||
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
|
||||
llvm::MemoryBuffer::getFile(ConfigFile.c_str());
|
||||
FS->getBufferForFile(ConfigFile.str());
|
||||
if (std::error_code EC = Text.getError()) {
|
||||
llvm::errs() << EC.message() << "\n";
|
||||
break;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include "clang/Frontend/TextDiagnosticPrinter.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#define DEBUG_TYPE "format-test"
|
||||
|
@ -11199,6 +11200,39 @@ TEST_F(FormatTest, FormatsTableGenCode) {
|
|||
verifyFormat("include \"a.td\"\ninclude \"b.td\"", Style);
|
||||
}
|
||||
|
||||
// Since this test case uses UNIX-style file path. We disable it for MS
|
||||
// compiler.
|
||||
#if !defined(_MSC_VER)
|
||||
|
||||
TEST(FormatStyle, GetStyleOfFile) {
|
||||
vfs::InMemoryFileSystem FS;
|
||||
// Test 1: format file in the same directory.
|
||||
ASSERT_TRUE(
|
||||
FS.addFile("/a/.clang-format", 0,
|
||||
llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: LLVM")));
|
||||
ASSERT_TRUE(
|
||||
FS.addFile("/a/test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int i;")));
|
||||
auto Style1 = getStyle("file", "/a/.clang-format", "Google", &FS);
|
||||
ASSERT_EQ(Style1, getLLVMStyle());
|
||||
|
||||
// Test 2: fallback to default.
|
||||
ASSERT_TRUE(
|
||||
FS.addFile("/b/test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int i;")));
|
||||
auto Style2 = getStyle("file", "/b/test.cpp", "Mozilla", &FS);
|
||||
ASSERT_EQ(Style2, getMozillaStyle());
|
||||
|
||||
// Test 3: format file in parent directory.
|
||||
ASSERT_TRUE(
|
||||
FS.addFile("/c/.clang-format", 0,
|
||||
llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: Google")));
|
||||
ASSERT_TRUE(FS.addFile("/c/sub/sub/sub/test.cpp", 0,
|
||||
llvm::MemoryBuffer::getMemBuffer("int i;")));
|
||||
auto Style3 = getStyle("file", "/c/sub/sub/sub/test.cpp", "LLVM", &FS);
|
||||
ASSERT_EQ(Style3, getGoogleStyle());
|
||||
}
|
||||
|
||||
#endif // _MSC_VER
|
||||
|
||||
class ReplacementTest : public ::testing::Test {
|
||||
protected:
|
||||
tooling::Replacement createReplacement(SourceLocation Start, unsigned Length,
|
||||
|
|
Loading…
Reference in New Issue