diff options
author | Jade Lovelace <lix@jade.fyi> | 2024-03-29 20:26:38 -0700 |
---|---|---|
committer | jade <lix@jade.fyi> | 2024-04-06 04:40:19 +0000 |
commit | 43cf487c256395e03f2e10f1f66b3933f201a4e8 (patch) | |
tree | 7cd40af4daf8f3c40f50596bbaeb00f5bbe43676 /clang-tidy/FixIncludes.cc | |
parent | 194a1b91af6d8848e4cc0dfbdcc153ee2dbed140 (diff) |
Create clang-tidy check to rename all our includes
It is a little bit scuffed, but it seems to produce correct results. We
can run it at a later date when we want to explode every in-flight
commit in existence and then need to filter-branch them.
Fixes: https://git.lix.systems/lix-project/lix/issues/188
Change-Id: Id97e4651f78804a941d941df02c7c1b21ce453b6
Diffstat (limited to 'clang-tidy/FixIncludes.cc')
-rw-r--r-- | clang-tidy/FixIncludes.cc | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/clang-tidy/FixIncludes.cc b/clang-tidy/FixIncludes.cc new file mode 100644 index 000000000..8ba350243 --- /dev/null +++ b/clang-tidy/FixIncludes.cc @@ -0,0 +1,81 @@ +#include "FixIncludes.hh" +#include <clang-tidy/ClangTidyCheck.h> +#include <clang/Basic/Diagnostic.h> +#include <clang/Basic/SourceManager.h> +#include <clang/Lex/PPCallbacks.h> +#include <clang/Lex/Preprocessor.h> +#include <llvm/ADT/StringRef.h> +#include <llvm/Support/Debug.h> +#include <memory> +#include <set> +#include <string> + +namespace nix::clang_tidy { + +using namespace clang; +using namespace clang::tidy; + +class FixIncludesCallbacks : public PPCallbacks { +public: + ClangTidyCheck &Check; + Preprocessor &PP; + FixIncludesCallbacks(ClangTidyCheck &Check, Preprocessor &PP) + : Check(Check), PP(PP) {} + +private: + bool Ignore = false; + virtual void LexedFileChanged(FileID FID, LexedFileChangeReason Reason, + SrcMgr::CharacteristicKind FileType, + FileID PrevFID, SourceLocation Loc) override; + + virtual void InclusionDirective(SourceLocation HashLoc, + const Token &IncludeTok, StringRef FileName, + bool IsAngled, CharSourceRange FilenameRange, + OptionalFileEntryRef File, + StringRef SearchPath, StringRef RelativePath, + const Module *Imported, + SrcMgr::CharacteristicKind FileType) override; +}; + +void FixIncludesCallbacks::LexedFileChanged(FileID, LexedFileChangeReason, + SrcMgr::CharacteristicKind FileType, + FileID, SourceLocation) { + Ignore = FileType != SrcMgr::C_User; +} + +void FixIncludesCallbacks::InclusionDirective( + SourceLocation, const Token &, StringRef, bool, + CharSourceRange FilenameRange, OptionalFileEntryRef File, StringRef, + StringRef, const Module *, SrcMgr::CharacteristicKind) { + if (Ignore) + return; + + // FIXME: this is kinda evil, but this is a one-time fixup + const std::string SourceDir = "src/"; + + if (File && File->getNameAsRequested().contains(SourceDir)) { + StringRef Name = File->getNameAsRequested(); + auto Idx = Name.find(SourceDir); + assert(Idx != std::string::npos); + StringRef Suffix = Name.drop_front(Idx + SourceDir.length()); + + if (!Suffix.starts_with("lib")) { + llvm::dbgs() << "ignored: " << Suffix << "\n"; + return; + } + + auto Diag = Check.diag(FilenameRange.getBegin(), + "include needs to specify the source subdir"); + + Diag << FilenameRange + << FixItHint::CreateReplacement(FilenameRange, + ("\"" + Suffix + "\"").str()); + } +} + +void FixIncludesCheck::registerPPCallbacks(const SourceManager &, + Preprocessor *PP, Preprocessor *) { + PP->addPPCallbacks(std::make_unique<FixIncludesCallbacks>(*this, *PP)); +} + +}; // namespace nix::clang_tidy |