brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.1 KiB · 609563d Raw
103 lines · cpp
1//===-- RecordTest.cpp ----------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "clang-include-cleaner/Types.h"10#include "clang/Basic/FileManager.h"11#include "clang/Basic/FileSystemOptions.h"12#include "clang/Tooling/Inclusions/StandardLibrary.h"13#include "llvm/ADT/IntrusiveRefCntPtr.h"14#include "llvm/Support/VirtualFileSystem.h"15#include "gmock/gmock.h"16#include "gtest/gtest.h"17 18namespace clang::include_cleaner {19namespace {20using testing::ElementsAre;21using testing::IsEmpty;22using testing::UnorderedElementsAre;23 24// Matches an Include* on the specified line;25MATCHER_P(line, N, "") { return arg->Line == (unsigned)N; }26 27TEST(RecordedIncludesTest, Match) {28  // We're using synthetic data, but need a FileManager to obtain FileEntry*s.29  // Ensure it doesn't do any actual IO.30  auto FS = llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>();31  FileManager FM(FileSystemOptions{});32  FileEntryRef A = FM.getVirtualFileRef("/path/a", /*Size=*/0, time_t{});33  FileEntryRef B = FM.getVirtualFileRef("/path/b", /*Size=*/0, time_t{});34 35  Includes Inc;36  Inc.add(Include{"a", A, SourceLocation(), 1});37  Inc.add(Include{"a2", A, SourceLocation(), 2});38  Inc.add(Include{"b", B, SourceLocation(), 3});39  Inc.add(Include{"vector", B, SourceLocation(), 4});40  Inc.add(Include{"vector", B, SourceLocation(), 5});41  Inc.add(Include{"missing", std::nullopt, SourceLocation(), 6});42 43  EXPECT_THAT(Inc.match(A), ElementsAre(line(1), line(2)));44  EXPECT_THAT(Inc.match(B), ElementsAre(line(3), line(4), line(5)));45  EXPECT_THAT(Inc.match(*tooling::stdlib::Header::named("<vector>")),46              ElementsAre(line(4), line(5)));47}48 49TEST(RecordedIncludesTest, MatchVerbatim) {50  auto FS = llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>();51  FileManager FM(FileSystemOptions{});52  Includes Inc;53 54  // By default, a verbatim header only matches includes with the same spelling.55  auto Foo =56      FM.getVirtualFileRef("repo/lib/include/rel/foo.h", /*Size=*/0, time_t{});57  Inc.add(Include{"lib/include/rel/foo.h", Foo, SourceLocation(), 1});58  Inc.add(Include{"rel/foo.h", Foo, SourceLocation(), 2});59  EXPECT_THAT(Inc.match(Header("<rel/foo.h>")), ElementsAre(line(2)));60 61  // A verbatim header can match another spelling if the search path62  // suggests it's equivalent.63  auto Bar =64      FM.getVirtualFileRef("repo/lib/include/rel/bar.h", /*Size=*/0, time_t{});65  Inc.addSearchDirectory("repo/");66  Inc.addSearchDirectory("repo/lib/include");67  Inc.add(Include{"lib/include/rel/bar.h", Bar, SourceLocation(), 3});68  Inc.add(Include{"rel/bar.h", Bar, SourceLocation(), 4});69  EXPECT_THAT(Inc.match(Header("<rel/bar.h>")),70              UnorderedElementsAre(line(3), line(4)));71 72  // We don't apply this logic to system headers, though.73  auto Vector =74      FM.getVirtualFileRef("repo/lib/include/vector", /*Size=*/0, time_t{});75  Inc.add(Include{"lib/include/vector", Vector, SourceLocation(), 5});76  EXPECT_THAT(Inc.match(Header(*tooling::stdlib::Header::named("<vector>"))),77              IsEmpty());78}79 80TEST(RecordedIncludesTest, MatchVerbatimMixedAbsoluteRelative) {81  auto FS = llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>();82  FS->setCurrentWorkingDirectory("/working");83  FileManager FM(FileSystemOptions{});84  Includes Inc;85 86  auto Foo =87      FM.getVirtualFileRef("/working/rel1/rel2/foo.h", /*Size=*/0, time_t{});88  Inc.addSearchDirectory("rel1");89  Inc.addSearchDirectory("rel1/rel2");90  Inc.add(Include{"rel2/foo.h", Foo, SourceLocation(), 1});91  EXPECT_THAT(Inc.match(Header("<foo.h>")), IsEmpty());92 93  Inc = Includes{};94  auto Bar = FM.getVirtualFileRef("rel1/rel2/bar.h", /*Size=*/0, time_t{});95  Inc.addSearchDirectory("/working/rel1");96  Inc.addSearchDirectory("/working/rel1/rel2");97  Inc.add(Include{"rel2/bar.h", Bar, SourceLocation(), 1});98  EXPECT_THAT(Inc.match(Header("<bar.h>")), IsEmpty());99}100 101} // namespace102} // namespace clang::include_cleaner103