0x8000-0000 updated this revision to Diff 327653.
0x8000-0000 marked an inline comment as done.
0x8000-0000 added a comment.

Use regular expression for filtering out loop counter variables to ignore.

Fully document the options.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D97753/new/

https://reviews.llvm.org/D97753

Files:
  clang-tools-extra/clang-tidy/readability/CMakeLists.txt
  clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
  clang-tools-extra/clang-tidy/readability/VariableLengthCheck.cpp
  clang-tools-extra/clang-tidy/readability/VariableLengthCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/docs/clang-tidy/checks/readability-variable-length.rst
  clang-tools-extra/test/clang-tidy/checkers/readability-variable-length.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/readability-variable-length.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/readability-variable-length.cpp
@@ -0,0 +1,57 @@
+// RUN: %check_clang_tidy %s readability-variable-length %t
+
+struct myexcept
+{
+   int val;
+};
+
+void doIt();
+
+void tooShortVariableNames()
+{
+   int i = 5;
+// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: variable name 'i' is too short, expected at least 3 characters [readability-variable-length]
+
+   int jj = 6;
+// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: variable name 'jj' is too short, expected at least 3 characters [readability-variable-length]
+
+   for (int m = 0; m < 5; ++ m)
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: loop variable name 'm' is too short, expected at least 2 characters [readability-variable-length]
+   {
+      doIt();
+   }
+
+   try
+   {
+      doIt();
+   }
+   catch (const myexcept& x)
+// CHECK-MESSAGES: :[[@LINE-1]]:27: warning: exception variable name 'x' is too short, expected at least 2 characters [readability-variable-length]
+   {
+      doIt();
+   }
+}
+
+void longEnoughVariableNames()
+{
+   int var = 5;
+
+   for (int i = 0; i < 42; ++ i) // 'i' is default allowed, for historical reasons
+   {
+      doIt();
+   }
+
+   for (int kk = 0; kk < 42; ++ kk)
+   {
+      doIt();
+   }
+
+   try
+   {
+      doIt();
+   }
+   catch (const myexcept& ex)
+   {
+      doIt();
+   }
+}
Index: clang-tools-extra/docs/clang-tidy/checks/readability-variable-length.rst
===================================================================
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/readability-variable-length.rst
@@ -0,0 +1,70 @@
+.. title:: clang-tidy - readability-variable-length
+
+readability-variable-length
+===========================
+
+This check finds variables and function parameters whose length are too short.
+The desired name length is configurable.
+
+Special cases are supported for loop counters and for exception variable names.
+
+Options
+-------
+
+The following options are described below:
+
+ - :option:`MinimumLoopCounterNameLength`, :option:`IgnoredLoopCounterNames`
+ - :option:`MinimumVariableNameLength`, :option:`MinimumExceptionNameLength`
+
+.. option:: MinimumLoopCounterNameLength
+
+    Loop counter variables are expected to have a length of at least
+    `MinimumLoopCounterNameLength` characters (default is `2`).
+
+    .. code-block:: c++
+
+        // This warns that 'q' is too short.
+        for (int q = 0; q < size; ++ q) {
+            // ...
+        }
+
+.. option:: IgnoredLoopCounterNames
+
+    Specifies a regular expression for counter names that are to be ignored.
+    The default value is `^[ijk_]$`; the first three symbols for historical
+    reasons and the last one since it is frequently used as a "dont't care"
+    value, specifically in tools such as Google Benchmark.
+
+    .. code-block:: c++
+
+        // This does not warn by default, for historical reasons.
+        for (int i = 0; i < size; ++ i) {
+            // ...
+        }
+
+.. option:: MinimumExceptionNameLength
+
+    Exception clause variables are expected to have a length of at least
+    `MinimumExceptionNameLength` (default is `2`).
+
+    .. code-block:: c++
+
+        try {
+            // ...
+        }
+        // This warns that 'e' is too short.
+        catch (const std::exception& e) {
+            // ...
+        }
+
+.. option:: MinimumVariableNameLength
+
+    All other variables are expected to have at least a length of
+    `MinimumVariableNameLength` (default is `3`).
+
+    .. code-block:: c++
+
+        int i = 42;    // warns that 'i' is too short
+
+    This check does not have any fix suggestions in the general case since
+    variable names have semantic value.
Index: clang-tools-extra/docs/clang-tidy/checks/list.rst
===================================================================
--- clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -312,6 +312,7 @@
    `readability-uniqueptr-delete-release <readability-uniqueptr-delete-release.html>`_, "Yes"
    `readability-uppercase-literal-suffix <readability-uppercase-literal-suffix.html>`_, "Yes"
    `readability-use-anyofallof <readability-use-anyofallof.html>`_,
+   `readability-variable-length <readability-variable-length.html>`_,
    `zircon-temporary-objects <zircon-temporary-objects.html>`_,
 
 
Index: clang-tools-extra/docs/ReleaseNotes.rst
===================================================================
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -89,6 +89,11 @@
   Finds member initializations in the constructor body which can be placed into
   the initialization list instead.
 
+- New :doc:`readability-variable-length
+  <clang-tidy/checks/readability-variable-length>` check.
+
+  Finds variables and function arguments whose names are too short.
+
 New check aliases
 ^^^^^^^^^^^^^^^^^
 
Index: clang-tools-extra/clang-tidy/readability/VariableLengthCheck.h
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/readability/VariableLengthCheck.h
@@ -0,0 +1,43 @@
+//===--- VariableLengthCheck.h - clang-tidy ---------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_VARIABLELENGTHCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_VARIABLELENGTHCHECK_H
+
+#include "../ClangTidyCheck.h"
+#include "llvm/Support/Regex.h"
+
+namespace clang {
+namespace tidy {
+namespace readability {
+
+/// Warns about variable names whose length is too short.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/readability-variable-length.html
+class VariableLengthCheck : public ClangTidyCheck {
+public:
+  VariableLengthCheck(StringRef Name, ClangTidyContext *Context);
+  void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+
+private:
+  const unsigned MinimumVariableNameLength;
+  const unsigned MinimumLoopCounterNameLength;
+  const unsigned MinimumExceptionNameLength;
+
+  std::string IgnoredLoopCounterNamesInput;
+  llvm::Regex IgnoredLoopCounterNames;
+};
+
+} // namespace readability
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_VARIABLELENGTHCHECK_H
Index: clang-tools-extra/clang-tidy/readability/VariableLengthCheck.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/readability/VariableLengthCheck.cpp
@@ -0,0 +1,109 @@
+//===--- VariableLengthCheck.cpp - clang-tidy -----------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "VariableLengthCheck.h"
+#include "../utils/OptionsUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace readability {
+
+const unsigned DefaultMinimumVariableNameLength = 3;
+const unsigned DefaultMinimumLoopCounterNameLength = 2;
+const unsigned DefaultMinimumExceptionNameLength = 2;
+const char DefaultIgnoredLoopCounterNames[] = "^[ijk_]$";
+
+const char ErrorMessage[] = "%select{|exception |loop }0 variable name %1 is "
+                            "too short, expected at least %2 characters";
+
+VariableLengthCheck::VariableLengthCheck(StringRef Name,
+                                         ClangTidyContext *Context)
+    : ClangTidyCheck(Name, Context),
+      MinimumVariableNameLength(Options.get("MinimumVariableNameLength",
+                                            DefaultMinimumVariableNameLength)),
+      MinimumLoopCounterNameLength(Options.get(
+          "MinimumLoopCounterNameLength", DefaultMinimumLoopCounterNameLength)),
+      MinimumExceptionNameLength(Options.get(
+          "MinimumExceptionNameLength", DefaultMinimumExceptionNameLength)),
+      IgnoredLoopCounterNamesInput(Options.get("IgnoredLoopCounterNames",
+                                               DefaultIgnoredLoopCounterNames)),
+      IgnoredLoopCounterNames(IgnoredLoopCounterNamesInput) {}
+
+void VariableLengthCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
+  Options.store(Opts, "MinimumVariableNameLength", MinimumVariableNameLength);
+  Options.store(Opts, "MinimumLoopCounterNameLength",
+                MinimumLoopCounterNameLength);
+  Options.store(Opts, "MinimumExceptionNameLength", MinimumExceptionNameLength);
+  Options.store(Opts, "IgnoredLoopCounterNames", IgnoredLoopCounterNamesInput);
+}
+
+void VariableLengthCheck::registerMatchers(MatchFinder *Finder) {
+  if (MinimumLoopCounterNameLength > 1)
+    Finder->addMatcher(
+        forStmt(hasLoopInit(declStmt(forEach(varDecl().bind("loopVar"))))),
+        this);
+
+  if (MinimumExceptionNameLength > 1)
+    Finder->addMatcher(varDecl(hasParent(cxxCatchStmt())).bind("exceptionVar"),
+                       this);
+
+  if (MinimumVariableNameLength > 1)
+    Finder->addMatcher(
+        varDecl(unless(anyOf(hasParent(declStmt(hasParent(forStmt()))),
+                             hasParent(cxxCatchStmt()))))
+            .bind("standaloneVar"),
+        this);
+}
+
+void VariableLengthCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *StandaloneVar = Result.Nodes.getNodeAs<VarDecl>("standaloneVar");
+  if (StandaloneVar) {
+    if (!StandaloneVar->getIdentifier() ||
+        StandaloneVar->getName().size() >= MinimumVariableNameLength)
+      return;
+
+    diag(StandaloneVar->getLocation(), ErrorMessage)
+        << 0 << StandaloneVar << MinimumVariableNameLength;
+  }
+
+  const auto *ExceptionVar = Result.Nodes.getNodeAs<VarDecl>("exceptionVar");
+  if (ExceptionVar) {
+    if (!ExceptionVar->getIdentifier() ||
+        ExceptionVar->getName().size() >= MinimumExceptionNameLength)
+      return;
+
+    diag(ExceptionVar->getLocation(), ErrorMessage)
+        << 1 << ExceptionVar << MinimumExceptionNameLength;
+  }
+
+  const auto *LoopVar = Result.Nodes.getNodeAs<VarDecl>("loopVar");
+  if (LoopVar) {
+    if (!LoopVar->getIdentifier())
+      return;
+
+    const StringRef LoopVarName = LoopVar->getName();
+
+    if (LoopVarName.size() >= MinimumLoopCounterNameLength)
+      return;
+
+    const std::string LoopVarNameString{LoopVarName.data(), LoopVarName.size()};
+    if (IgnoredLoopCounterNames.match(LoopVarNameString))
+      return;
+
+    diag(LoopVar->getLocation(), ErrorMessage)
+        << 2 << LoopVar << MinimumLoopCounterNameLength;
+  }
+}
+
+} // namespace readability
+} // namespace tidy
+} // namespace clang
Index: clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
===================================================================
--- clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
+++ clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
@@ -47,6 +47,7 @@
 #include "UniqueptrDeleteReleaseCheck.h"
 #include "UppercaseLiteralSuffixCheck.h"
 #include "UseAnyOfAllOfCheck.h"
+#include "VariableLengthCheck.h"
 
 namespace clang {
 namespace tidy {
@@ -131,6 +132,8 @@
         "readability-uppercase-literal-suffix");
     CheckFactories.registerCheck<UseAnyOfAllOfCheck>(
         "readability-use-anyofallof");
+    CheckFactories.registerCheck<VariableLengthCheck>(
+        "readability-variable-length");
   }
 };
 
Index: clang-tools-extra/clang-tidy/readability/CMakeLists.txt
===================================================================
--- clang-tools-extra/clang-tidy/readability/CMakeLists.txt
+++ clang-tools-extra/clang-tidy/readability/CMakeLists.txt
@@ -44,6 +44,7 @@
   UniqueptrDeleteReleaseCheck.cpp
   UppercaseLiteralSuffixCheck.cpp
   UseAnyOfAllOfCheck.cpp
+  VariableLengthCheck.cpp
 
   LINK_LIBS
   clangTidy
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to