From b918f1c307b314daa44407bac60046630f13ed48 Mon Sep 17 00:00:00 2001 From: eldritch horrors Date: Wed, 26 Mar 2025 19:26:02 +0100 Subject: [PATCH] tidy: add a lint to forbid nlohmann::json::parse Change-Id: I165c7330d7ea7f17522ade8a0666d0d7d86b9d38 --- lix/libutil/json.hh | 1 + subprojects/lix-clang-tidy/DisallowedDecls.cc | 37 +++++++++++++++++++ subprojects/lix-clang-tidy/DisallowedDecls.hh | 21 +++++++++++ .../lix-clang-tidy/LixClangTidyChecks.cc | 2 + subprojects/lix-clang-tidy/meson.build | 1 + 5 files changed, 62 insertions(+) create mode 100644 subprojects/lix-clang-tidy/DisallowedDecls.cc create mode 100644 subprojects/lix-clang-tidy/DisallowedDecls.hh diff --git a/lix/libutil/json.hh b/lix/libutil/json.hh index 3d1a2a5ae..d30e38df6 100644 --- a/lix/libutil/json.hh +++ b/lix/libutil/json.hh @@ -163,6 +163,7 @@ template JSON parse(Source && source, std::optional context = {}) { try { + // NOLINTNEXTLINE(lix-disallowed-decls): this is the wrapper for that return JSON::parse(std::forward(source)); } catch (JSON::exception & e) { ParseError error{"failed to parse JSON: %s", e.what()}; diff --git a/subprojects/lix-clang-tidy/DisallowedDecls.cc b/subprojects/lix-clang-tidy/DisallowedDecls.cc new file mode 100644 index 000000000..41c735c9e --- /dev/null +++ b/subprojects/lix-clang-tidy/DisallowedDecls.cc @@ -0,0 +1,37 @@ +#include "DisallowedDecls.hh" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace nix::clang_tidy { +using namespace clang::ast_matchers; +using namespace clang; + +void DisallowedDeclsCheck::registerMatchers(ast_matchers::MatchFinder *Finder) { + Finder->addMatcher( + traverse(clang::TK_AsIs, + callExpr(callee(cxxMethodDecl(hasName("parse"), + ofClass(isSameOrDerivedFrom( + "nlohmann::basic_json"))))) + .bind("json-parse")), + this); +} + +void DisallowedDeclsCheck::check( + const ast_matchers::MatchFinder::MatchResult &Result) { + + if (auto MatchedParse = Result.Nodes.getNodeAs("json-parse")) { + auto Diag = diag(MatchedParse->getExprLoc(), + "using nlohmann::basic_json::parse is disallowed, use the lix wrapper instead"); + Diag << FixItHint::CreateReplacement(MatchedParse->getCallee()->getSourceRange(), + "json::parse"); + } +} +}; // namespace nix::clang_tidy diff --git a/subprojects/lix-clang-tidy/DisallowedDecls.hh b/subprojects/lix-clang-tidy/DisallowedDecls.hh new file mode 100644 index 000000000..c4c5659e1 --- /dev/null +++ b/subprojects/lix-clang-tidy/DisallowedDecls.hh @@ -0,0 +1,21 @@ +#pragma once +///@file + +#include +#include +#include + +namespace nix::clang_tidy { + +using namespace clang; +using namespace clang::tidy; +using namespace llvm; + +class DisallowedDeclsCheck : public ClangTidyCheck { +public: + DisallowedDeclsCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; +}; +}; // namespace nix::clang_tidy diff --git a/subprojects/lix-clang-tidy/LixClangTidyChecks.cc b/subprojects/lix-clang-tidy/LixClangTidyChecks.cc index 4bcd5bc89..62da97f2f 100644 --- a/subprojects/lix-clang-tidy/LixClangTidyChecks.cc +++ b/subprojects/lix-clang-tidy/LixClangTidyChecks.cc @@ -1,5 +1,6 @@ #include #include +#include "DisallowedDecls.hh" #include "HasPrefixSuffix.hh" #include "CharPtrCast.hh" #include "NeverAsync.hh" @@ -14,6 +15,7 @@ class NixClangTidyChecks : public ClangTidyModule { CheckFactories.registerCheck("lix-hasprefixsuffix"); CheckFactories.registerCheck("lix-charptrcast"); CheckFactories.registerCheck("lix-never-async"); + CheckFactories.registerCheck("lix-disallowed-decls"); } }; diff --git a/subprojects/lix-clang-tidy/meson.build b/subprojects/lix-clang-tidy/meson.build index 7b5948369..174880ca4 100644 --- a/subprojects/lix-clang-tidy/meson.build +++ b/subprojects/lix-clang-tidy/meson.build @@ -6,6 +6,7 @@ project('lix-clang-tidy', ['cpp', 'c'], llvm = dependency('Clang', version: '>= 16', modules: ['libclang']) sources = files( 'CharPtrCast.cc', + 'DisallowedDecls.cc', 'HasPrefixSuffix.cc', 'LixClangTidyChecks.cc', 'NeverAsync.cc',