AbseilMatcher.h 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. //===- AbseilMatcher.h - clang-tidy ---------------------------------------===//
  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-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "clang/AST/ASTContext.h"
  9. #include "clang/ASTMatchers/ASTMatchFinder.h"
  10. #include <algorithm>
  11. namespace clang::ast_matchers {
  12. /// Matches AST nodes that were found within Abseil files.
  13. ///
  14. /// Example matches Y but not X
  15. /// (matcher = cxxRecordDecl(isInAbseilFile())
  16. /// \code
  17. /// #include "absl/strings/internal-file.h"
  18. /// class X {};
  19. /// \endcode
  20. /// absl/strings/internal-file.h:
  21. /// \code
  22. /// class Y {};
  23. /// \endcode
  24. ///
  25. /// Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>,
  26. /// Matcher<NestedNameSpecifierLoc>
  27. AST_POLYMORPHIC_MATCHER(
  28. isInAbseilFile, AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc,
  29. NestedNameSpecifierLoc)) {
  30. auto &SourceManager = Finder->getASTContext().getSourceManager();
  31. SourceLocation Loc = SourceManager.getSpellingLoc(Node.getBeginLoc());
  32. if (Loc.isInvalid())
  33. return false;
  34. const FileEntry *FileEntry =
  35. SourceManager.getFileEntryForID(SourceManager.getFileID(Loc));
  36. if (!FileEntry)
  37. return false;
  38. // Determine whether filepath contains "absl/[absl-library]" substring, where
  39. // [absl-library] is AbseilLibraries list entry.
  40. StringRef Path = FileEntry->getName();
  41. static constexpr llvm::StringLiteral AbslPrefix("absl/");
  42. size_t PrefixPosition = Path.find(AbslPrefix);
  43. if (PrefixPosition == StringRef::npos)
  44. return false;
  45. Path = Path.drop_front(PrefixPosition + AbslPrefix.size());
  46. static const char *AbseilLibraries[] = {
  47. "algorithm", "base", "container", "debugging", "flags",
  48. "hash", "iterator", "memory", "meta", "numeric",
  49. "profiling", "random", "status", "strings", "synchronization",
  50. "time", "types", "utility"};
  51. return llvm::any_of(AbseilLibraries, [&](const char *Library) {
  52. return Path.startswith(Library);
  53. });
  54. }
  55. } // namespace clang::ast_matchers