Author: Carlos Galvez Date: 2023-04-10T19:31:33Z New Revision: 132f1d31fd66c30baf9773bf8f37b36a40fa7039
URL: https://github.com/llvm/llvm-project/commit/132f1d31fd66c30baf9773bf8f37b36a40fa7039 DIFF: https://github.com/llvm/llvm-project/commit/132f1d31fd66c30baf9773bf8f37b36a40fa7039.diff LOG: [clang-tidy] Support specifying checks as a list in the config file Specifying checks as a string is convenient for quickly using clang-tidy to run a handful of checks. However it is not suitable for projects that have a long list of enabled or disabled checks. It is specially troublesome in case one wants to interleave comments with the checks, to explain why they are enabled or disabled. Currently this can be achieved via multiline strings in YAML, but it's error-prone. For example, comments must end with a comma for clang-tidy to continue processing the list of globs; a missing comma will make clang-tidy silently ignore the rest of the list. Instead, enable passing a native YAML list to the "Checks" option in the config file. The implementation is done such that the old behavior is kept: a user can pass a string or a list. We can consider deprecating passing the checks as a string altogether in a future release, to simplify the internal logic of the YAML parser. Fixes https://github.com/llvm/llvm-project/issues/51428 Differential Revision: https://reviews.llvm.org/D147876 Added: clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-file/config-file-list-bracket clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-file/config-file-list-dash Modified: clang-tools-extra/clang-tidy/ClangTidyOptions.cpp clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp clang-tools-extra/docs/ReleaseNotes.rst clang-tools-extra/docs/clang-tidy/index.rst clang-tools-extra/test/clang-tidy/infrastructure/config-file.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp index 84defccde513e..afa88cb4f80d1 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp +++ b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp @@ -117,10 +117,48 @@ void yamlize(IO &IO, ClangTidyOptions::OptionMap &Options, bool, } } +struct ChecksVariant { + std::optional<std::string> AsString; + std::optional<std::vector<std::string>> AsVector; +}; + +template <> +void yamlize(IO &IO, ChecksVariant &Checks, bool, EmptyContext &Ctx) { + if (!IO.outputting()) { + // Special case for reading from YAML + // Must support reading from both a string or a list + Input &I = reinterpret_cast<Input &>(IO); + if (isa<ScalarNode, BlockScalarNode>(I.getCurrentNode())) { + Checks.AsString = std::string(); + yamlize(IO, *Checks.AsString, true, Ctx); + } else if (isa<SequenceNode>(I.getCurrentNode())) { + Checks.AsVector = std::vector<std::string>(); + yamlize(IO, *Checks.AsVector, true, Ctx); + } else { + IO.setError("expected string or sequence"); + } + } +} + +static void mapChecks(IO &IO, std::optional<std::string> &Checks) { + if (IO.outputting()) { + // Output always a string + IO.mapOptional("Checks", Checks); + } else { + // Input as either a string or a list + ChecksVariant ChecksAsVariant; + IO.mapOptional("Checks", ChecksAsVariant); + if (ChecksAsVariant.AsString) + Checks = ChecksAsVariant.AsString; + else if (ChecksAsVariant.AsVector) + Checks = llvm::join(*ChecksAsVariant.AsVector, ","); + } +} + template <> struct MappingTraits<ClangTidyOptions> { static void mapping(IO &IO, ClangTidyOptions &Options) { bool Ignored = false; - IO.mapOptional("Checks", Options.Checks); + mapChecks(IO, Options.Checks); IO.mapOptional("WarningsAsErrors", Options.WarningsAsErrors); IO.mapOptional("HeaderFileExtensions", Options.HeaderFileExtensions); IO.mapOptional("ImplementationFileExtensions", diff --git a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp index 09162995a0974..2bed6dfda3a0a 100644 --- a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp +++ b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp @@ -52,7 +52,9 @@ Configuration files: options. Example: CheckOptions: some-check.SomeOption: 'some value' - Checks - Same as '--checks'. + Checks - Same as '--checks'. Additionally, the list of + globs can be specified as a list instead of a + string. ExtraArgs - Same as '--extra-args'. ExtraArgsBefore - Same as '--extra-args-before'. FormatStyle - Same as '--format-style'. diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index cb10385d8e87f..9c5b86fc8606d 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -98,6 +98,9 @@ Improvements to clang-tidy `ImplementationFileExtensions`, replacing the check-local options of the same name. +- Support specifying `Checks` as a YAML list in the `.clang-tidy` configuration + file. + New checks ^^^^^^^^^^ diff --git a/clang-tools-extra/docs/clang-tidy/index.rst b/clang-tools-extra/docs/clang-tidy/index.rst index 899c3ea6ed540..444d03d6cb08a 100644 --- a/clang-tools-extra/docs/clang-tidy/index.rst +++ b/clang-tools-extra/docs/clang-tidy/index.rst @@ -259,7 +259,9 @@ An overview of all the command-line options: options. Example: CheckOptions: some-check.SomeOption: 'some value' - Checks - Same as '--checks'. + Checks - Same as '--checks'. Additionally, the list of + globs can be specified as a list instead of a + string. ExtraArgs - Same as '--extra-args'. ExtraArgsBefore - Same as '--extra-args-before'. FormatStyle - Same as '--format-style'. diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-file/config-file-list-bracket b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-file/config-file-list-bracket new file mode 100644 index 0000000000000..d2bfe57880c2b --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-file/config-file-list-bracket @@ -0,0 +1,6 @@ +Checks: [ + "-*", + "hicpp-uppercase-literal-suffix", + "hicpp-use-auto", + "hicpp-use-emplace", +] diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-file/config-file-list-dash b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-file/config-file-list-dash new file mode 100644 index 0000000000000..ce1c88d1148cb --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-file/config-file-list-dash @@ -0,0 +1,5 @@ +Checks: + - "-*" + - "hicpp-uppercase-literal-suffix" + - "hicpp-use-auto" + - "hicpp-use-emplace" diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/config-file.cpp b/clang-tools-extra/test/clang-tidy/infrastructure/config-file.cpp index 16b216a1d4f69..b929fb15193d1 100644 --- a/clang-tools-extra/test/clang-tidy/infrastructure/config-file.cpp +++ b/clang-tools-extra/test/clang-tidy/infrastructure/config-file.cpp @@ -6,3 +6,15 @@ // CHECK-SPACES-NEXT: hicpp-use-auto // CHECK-SPACES-NEXT: hicpp-use-emplace // CHECK-SPACES-EMPTY: +// RUN: clang-tidy -config-file=%S/Inputs/config-file/config-file-list-dash --list-checks -- | FileCheck %s -check-prefix=CHECK-LIST-DASH +// CHECK-LIST-DASH: Enabled checks: +// CHECK-LIST-DASH-NEXT: hicpp-uppercase-literal-suffix +// CHECK-LIST-DASH-NEXT: hicpp-use-auto +// CHECK-LIST-DASH-NEXT: hicpp-use-emplace +// CHECK-LIST-DASH-EMPTY: +// RUN: clang-tidy -config-file=%S/Inputs/config-file/config-file-list-bracket --list-checks -- | FileCheck %s -check-prefix=CHECK-LIST-BRACKET +// CHECK-LIST-BRACKET: Enabled checks: +// CHECK-LIST-BRACKET-NEXT: hicpp-uppercase-literal-suffix +// CHECK-LIST-BRACKET-NEXT: hicpp-use-auto +// CHECK-LIST-BRACKET-NEXT: hicpp-use-emplace +// CHECK-LIST-BRACKET-EMPTY: _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits