aboutsummaryrefslogtreecommitdiff
path: root/clang-tidy
diff options
context:
space:
mode:
authorJade Lovelace <lix@jade.fyi>2024-03-29 20:26:38 -0700
committerjade <lix@jade.fyi>2024-04-06 04:40:19 +0000
commit43cf487c256395e03f2e10f1f66b3933f201a4e8 (patch)
tree7cd40af4daf8f3c40f50596bbaeb00f5bbe43676 /clang-tidy
parent194a1b91af6d8848e4cc0dfbdcc153ee2dbed140 (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')
-rw-r--r--clang-tidy/.editorconfig4
-rw-r--r--clang-tidy/FixIncludes.cc81
-rw-r--r--clang-tidy/FixIncludes.hh21
-rw-r--r--clang-tidy/LixClangTidyChecks.cc (renamed from clang-tidy/NixClangTidyChecks.cc)6
-rw-r--r--clang-tidy/meson.build11
5 files changed, 118 insertions, 5 deletions
diff --git a/clang-tidy/.editorconfig b/clang-tidy/.editorconfig
new file mode 100644
index 000000000..19ee09eec
--- /dev/null
+++ b/clang-tidy/.editorconfig
@@ -0,0 +1,4 @@
+# LLVM style code is 2-space indented
+[*.{cc,hh}]
+indent_style = space
+indent_size = 2
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
diff --git a/clang-tidy/FixIncludes.hh b/clang-tidy/FixIncludes.hh
new file mode 100644
index 000000000..ea890cd39
--- /dev/null
+++ b/clang-tidy/FixIncludes.hh
@@ -0,0 +1,21 @@
+#pragma once
+///@file
+
+#include <clang-tidy/ClangTidyCheck.h>
+#include <clang/ASTMatchers/ASTMatchFinder.h>
+#include <llvm/ADT/StringRef.h>
+
+namespace nix::clang_tidy {
+
+using namespace clang;
+using namespace clang::tidy;
+
+class FixIncludesCheck : public ClangTidyCheck {
+ public:
+ FixIncludesCheck(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context) {}
+
+ void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) override;
+};
+
+};
diff --git a/clang-tidy/NixClangTidyChecks.cc b/clang-tidy/LixClangTidyChecks.cc
index 8f0309107..b3503dd3a 100644
--- a/clang-tidy/NixClangTidyChecks.cc
+++ b/clang-tidy/LixClangTidyChecks.cc
@@ -1,5 +1,6 @@
#include <clang-tidy/ClangTidyModule.h>
#include <clang-tidy/ClangTidyModuleRegistry.h>
+#include "FixIncludes.hh"
#include "HasPrefixSuffix.hh"
namespace nix::clang_tidy {
@@ -9,9 +10,10 @@ using namespace clang::tidy;
class NixClangTidyChecks : public ClangTidyModule {
public:
void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
- CheckFactories.registerCheck<HasPrefixSuffixCheck>("nix-hasprefixsuffix");
+ CheckFactories.registerCheck<HasPrefixSuffixCheck>("lix-hasprefixsuffix");
+ CheckFactories.registerCheck<FixIncludesCheck>("lix-fixincludes");
}
};
-static ClangTidyModuleRegistry::Add<NixClangTidyChecks> X("nix-module", "Adds nix specific checks");
+static ClangTidyModuleRegistry::Add<NixClangTidyChecks> X("lix-module", "Adds lix specific checks");
};
diff --git a/clang-tidy/meson.build b/clang-tidy/meson.build
index 48770e39f..c59164a72 100644
--- a/clang-tidy/meson.build
+++ b/clang-tidy/meson.build
@@ -1,8 +1,13 @@
-project('nix-clang-tidy', ['cpp', 'c'],
+project('lix-clang-tidy', ['cpp', 'c'],
version : '0.1',
default_options : ['warning_level=3', 'cpp_std=c++20'])
llvm = dependency('Clang', version: '>= 14', modules: ['libclang'])
-sources = ['HasPrefixSuffix.cc', 'NixClangTidyChecks.cc']
-shared_module('nix-clang-tidy', sources,
+sources = files(
+ 'HasPrefixSuffix.cc',
+ 'LixClangTidyChecks.cc',
+ 'FixIncludes.cc',
+)
+
+shared_module('lix-clang-tidy', sources,
dependencies: llvm)