blob: 335c333573f43bdb0e5f9f55bc6c8cb0f6efe1dc [file] [log] [blame]
//===- AbseilMatcher.h - clang-tidy ---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include <algorithm>
namespace clang {
namespace ast_matchers {
/// Matches AST nodes that were found within Abseil files.
///
/// Example matches Y but not X
/// (matcher = cxxRecordDecl(isInAbseilFile())
/// \code
/// #include "absl/strings/internal-file.h"
/// class X {};
/// \endcode
/// absl/strings/internal-file.h:
/// \code
/// class Y {};
/// \endcode
///
/// Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>,
/// Matcher<NestedNameSpecifierLoc>
AST_POLYMORPHIC_MATCHER(
isInAbseilFile, AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc,
NestedNameSpecifierLoc)) {
auto &SourceManager = Finder->getASTContext().getSourceManager();
SourceLocation Loc = SourceManager.getSpellingLoc(Node.getBeginLoc());
if (Loc.isInvalid())
return false;
const FileEntry *FileEntry =
SourceManager.getFileEntryForID(SourceManager.getFileID(Loc));
if (!FileEntry)
return false;
// Determine whether filepath contains "absl/[absl-library]" substring, where
// [absl-library] is AbseilLibraries list entry.
StringRef Path = FileEntry->getName();
static constexpr llvm::StringLiteral AbslPrefix("absl/");
size_t PrefixPosition = Path.find(AbslPrefix);
if (PrefixPosition == StringRef::npos)
return false;
Path = Path.drop_front(PrefixPosition + AbslPrefix.size());
static const char *AbseilLibraries[] = {"algorithm", "base",
"container", "debugging",
"flags", "hash",
"iterator", "memory",
"meta", "numeric",
"random", "status",
"strings", "synchronization",
"time", "types",
"utility"};
return llvm::any_of(AbseilLibraries, [&](const char *Library) {
return Path.startswith(Library);
});
}
} // namespace ast_matchers
} // namespace clang