diff --git a/docs/mkdocs/docs/api/macros/json_use_implicit_conversions.md b/docs/mkdocs/docs/api/macros/json_use_implicit_conversions.md index 0a5ad4df4..3fe684c66 100644 --- a/docs/mkdocs/docs/api/macros/json_use_implicit_conversions.md +++ b/docs/mkdocs/docs/api/macros/json_use_implicit_conversions.md @@ -23,6 +23,8 @@ By default, implicit conversions are enabled. You can prepare existing code by already defining `JSON_USE_IMPLICIT_CONVERSIONS` to `0` and replace any implicit conversions with calls to [`get`](../basic_json/get.md). + The [clang-tidy modernize-nlohmann-json-explicit-conversions](../../integration/clang-tidy.md#modernize-nlohmann-json-explicit-conversions) + check can help to do this automatically. !!! hint "CMake option" diff --git a/docs/mkdocs/docs/integration/clang-tidy.md b/docs/mkdocs/docs/integration/clang-tidy.md new file mode 100644 index 000000000..ed77696e1 --- /dev/null +++ b/docs/mkdocs/docs/integration/clang-tidy.md @@ -0,0 +1,81 @@ +# Clang-Tidy + +The library comes with a [clang-tidy](https://clang.llvm.org/extra/clang-tidy/) plugin. +It is disabled by default but can be enabled by enabling the `JSON_ClangTidyPlugin` [CMake option](cmake.md#json_clangtidyplugin). +Clang-tidy [Plugins](https://clang.llvm.org/extra/clang-tidy/ExternalClang-TidyExamples.html) are only supported by Clang 16 and later. + +## Building the plugin + +You will need to have the development files matching your version of clang-tidy installed to build the plugin. +For example, if you are running on a Debian-derived Linux distribution: + +```sh +apt install clang-tidy libclang-dev +``` +but if this installs a version that is older than Clang 16 then you might be able to specify a newer version. For example: +```sh +apt install clang-tidy-19 libclang-19-dev +``` + +```sh +mkdir build +cd build +cmake -DJSON_ClangTidyPlugin=ON .. +cmake -build . +``` + +# Running the plugin +To tell clang-tidy to use the plugin you must pass a path to it as an argument to the `-load` option. +For example, you can run clang-tidy with only the _modernize-nlohmann-json-explicit-conversion_ check using the plugin on a single file with: +```sh +clang-tidy -load .../path/to/build/clang_tidy_plugin/libNlohmannJsonClangTidyPlugin.so -checks='-*,modernize-nlohmann-json-explicit-conversions` -fix source.cpp +clang-tidy +``` +or you can create a `.clang-tidy` file to enable the checks you require. + +# Checks + +At the moment the plugin contains only a single check. + +## modernize-nlohmann-json-explicit-conversions + +This check converts code that takes advantage of [implicit conversions](../api/macros/json_use_implicit_conversions.md) to use explicit `get()` calls using the correct templated type. +For example, it turns: +```c++ +void f(const nlohmann::json &j1, const nlohmann::json &j2) +{ + int i = j1; + double d = j2.at("value"); + bool b = *j2.find("valid"); + std::cout << i << " " << d << " " << b << "\n"; +} +``` +into +```c++ +void f(const nlohmann::json &j1, const nlohmann::json &j2) +{ + int i = j1.get(); + double d = j2.at("value").get(); + bool b = j2.find("valid")->get(); + std::cout << i << " " << d << " " << b << "\n"; +} +``` +by knowing what the target type is for the implicit conversion and turning +that into an explicit call to the `get()` method with that type as the +template parameter. + +Unfortunately the check does not work very well if the implicit conversion +occurs in templated code or in a system header. For example, the following +won't be fixed because the implicit conversion will happen inside +`std::optional`'s constructor: +```c++ +void f(const nlohmann::json &j) +{ + std::optional oi; + const auto &it = j.find("value"); + if (it != j.end()) + oi = *it; + // ... +} +``` +After you have run this check you can set [JSON_USE_IMPLICIT_CONVERSIONS=0](../api/macros/json_use_implicit_conversions.md) to find any occurrences that the check have not been fixed automatically. diff --git a/docs/mkdocs/docs/integration/cmake.md b/docs/mkdocs/docs/integration/cmake.md index 69c8030f1..17bc39cd1 100644 --- a/docs/mkdocs/docs/integration/cmake.md +++ b/docs/mkdocs/docs/integration/cmake.md @@ -131,6 +131,10 @@ Build the unit tests when [`BUILD_TESTING`](https://cmake.org/cmake/help/latest/ Enable CI build targets. The exact targets are used during the several CI steps and are subject to change without notice. This option is `OFF` by default. +### `JSON_ClangTidyPlugin` + +Enable building the [clang-tidy plugin](clang-tidy.md). This option is `OFF` by default. + ### `JSON_Diagnostics` Enable [extended diagnostic messages](../home/exceptions.md#extended-diagnostic-messages) by defining macro [`JSON_DIAGNOSTICS`](../api/macros/json_diagnostics.md). This option is `OFF` by default. diff --git a/docs/mkdocs/mkdocs.yml b/docs/mkdocs/mkdocs.yml index 7a89219fb..b0254943e 100644 --- a/docs/mkdocs/mkdocs.yml +++ b/docs/mkdocs/mkdocs.yml @@ -93,6 +93,7 @@ nav: - Integration: - integration/index.md - integration/migration_guide.md + - integration/clang-tidy.md - integration/cmake.md - integration/package_managers.md - integration/pkg-config.md