[PATCH] D76606: [clang-tidy] Warn on invalid "case" configurations for readability-identifier-naming
Nathan James via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 23 06:31:06 PDT 2020
njames93 created this revision.
njames93 added reviewers: aaron.ballman, alexfh.
Herald added subscribers: cfe-commits, xazax.hun.
Herald added a project: clang.
njames93 marked 2 inline comments as done.
njames93 added a project: clang-tools-extra.
njames93 added a comment.
I'm not too sure how many other checks are like this, but I feel that this functionality could maybe be brought out of this check and into the Options to let more checks that take enum like configurations to use it.
================
Comment at: clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp:154
+ llvm::errs() << "warning: Invalid case style '" << CaseValue
+ << "' for readability-identifier-naming." << CaseOptionName;
+ constexpr StringRef AcceptibleNames[] = {
----------------
Unsure about hardcoding the check-name as it could be ran under an alias. However there is no way for a ClangTidyCheck to get the name its ran as. `ClangTidyCheck::CheckName` is `private`, maybe a protected getter would be wise.
================
Comment at: clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp:177
+ if (EditDistance < 3)
+ llvm::errs() << ": did you mean '" << Closest << "'\n";
+ else
----------------
I feel its safer not assuming the fix and instead letting the user modify their configuration, WDYT?
Issue a warning (and potential fix hint) when an invalid case value is supplied to readability-identifier-naming configuration.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D76606
Files:
clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming-case-validation.cpp
Index: clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming-case-validation.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming-case-validation.cpp
@@ -0,0 +1,16 @@
+// RUN: clang-tidy %s -checks=readability-identifier-naming \
+// RUN: -config="{CheckOptions: [\
+// RUN: {key: readability-identifier-naming.FunctionCase, value: camelback}, \
+// RUN: {key: readability-identifier-naming.VariableCase, value: camelBack}, \
+// RUN: {key: readability-identifier-naming.ClassCase, value: UUPER_CASE}, \
+// RUN: {key: readability-identifier-naming.StructCase, value: CAMEL}, \
+// RUN: {key: readability-identifier-naming.EnumCase, value: AnY_cASe}, \
+// RUN: ]}" 2>&1 | FileCheck %s --implicit-check-not warning
+
+
+// CHECK-DAG: warning: Invalid case style 'camelback' for readability-identifier-naming.FunctionCase: did you mean 'camelBack'{{$}}
+// CHECK-DAG: warning: Invalid case style 'UUPER_CASE' for readability-identifier-naming.ClassCase: did you mean 'UPPER_CASE'{{$}}
+// Don't try to suggest an alternative for 'CAMEL'
+// CHECK-DAG: warning: Invalid case style 'CAMEL' for readability-identifier-naming.StructCase{{$}}
+// This fails on the EditDistance, but as it matches ignoring case suggest the correct value
+// CHECK-DAG: warning: Invalid case style 'AnY_cASe' for readability-identifier-naming.EnumCase: did you mean 'aNy_CasE'{{$}}
Index: clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
===================================================================
--- clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
+++ clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
@@ -95,6 +95,15 @@
};
#undef NAMING_KEYS
+
+#define CASE_KEYS(m) \
+ m("aNy_CasE", CT_AnyCase) \
+ m("lower_case", CT_LowerCase) \
+ m("UPPER_CASE", CT_UpperCase) \
+ m("camelBack", CT_CamelBack) \
+ m("CamelCase", CT_CamelCase) \
+ m("Camel_Snake_Case", CT_CamelSnakeCase) \
+ m("camel_Snake_Back", CT_CamelSnakeBack)
// clang-format on
namespace {
@@ -131,19 +140,44 @@
IgnoreMainLikeFunctions(Options.get("IgnoreMainLikeFunctions", 0)) {
auto const fromString = [](StringRef Str) {
return llvm::StringSwitch<llvm::Optional<CaseType>>(Str)
- .Case("aNy_CasE", CT_AnyCase)
- .Case("lower_case", CT_LowerCase)
- .Case("UPPER_CASE", CT_UpperCase)
- .Case("camelBack", CT_CamelBack)
- .Case("CamelCase", CT_CamelCase)
- .Case("Camel_Snake_Case", CT_CamelSnakeCase)
- .Case("camel_Snake_Back", CT_CamelSnakeBack)
- .Default(llvm::None);
+#define CASE(NAME, ENUM) .Case(NAME, ENUM)
+ CASE_KEYS(CASE)
+#undef CASE
+ .Default(llvm::None);
};
-
for (auto const &Name : StyleNames) {
- auto const caseOptional =
- fromString(Options.get((Name + "Case").str(), ""));
+ auto CaseOptionName = (Name + "Case").str();
+ auto CaseValue = Options.get(CaseOptionName, "");
+ auto const caseOptional = fromString(CaseValue);
+ if (!caseOptional && !CaseValue.empty()) {
+ llvm::errs() << "warning: Invalid case style '" << CaseValue
+ << "' for readability-identifier-naming." << CaseOptionName;
+ constexpr StringRef AcceptibleNames[] = {
+#define CASE(NAME, ENUM) NAME,
+ CASE_KEYS(CASE)
+#undef CASE
+ };
+ StringRef Closest = "";
+ unsigned EditDistance = -1u;
+ for (StringRef CheckMatch : AcceptibleNames) {
+ if (CheckMatch.equals_lower(
+ CaseValue)) { // bad case just suggest the fix straight away
+ EditDistance = 0;
+ Closest = CheckMatch;
+ break;
+ }
+ unsigned Distance =
+ llvm::StringRef(CaseValue).edit_distance(CheckMatch);
+ if (Distance < EditDistance) {
+ EditDistance = Distance;
+ Closest = CheckMatch;
+ }
+ }
+ if (EditDistance < 3)
+ llvm::errs() << ": did you mean '" << Closest << "'\n";
+ else
+ llvm::errs() << '\n';
+ }
auto prefix = Options.get((Name + "Prefix").str(), "");
auto postfix = Options.get((Name + "Suffix").str(), "");
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D76606.252008.patch
Type: text/x-patch
Size: 4286 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200323/2b5886be/attachment.bin>
More information about the cfe-commits
mailing list