IdentifierLengthCheck.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. //===--- IdentifierLengthCheck.cpp - clang-tidy
  2. //-----------------------------===//
  3. //
  4. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  5. // See https://llvm.org/LICENSE.txt for license information.
  6. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "IdentifierLengthCheck.h"
  10. #include "../utils/OptionsUtils.h"
  11. #include "clang/AST/ASTContext.h"
  12. #include "clang/ASTMatchers/ASTMatchFinder.h"
  13. using namespace clang::ast_matchers;
  14. namespace clang::tidy::readability {
  15. const unsigned DefaultMinimumVariableNameLength = 3;
  16. const unsigned DefaultMinimumLoopCounterNameLength = 2;
  17. const unsigned DefaultMinimumExceptionNameLength = 2;
  18. const unsigned DefaultMinimumParameterNameLength = 3;
  19. const char DefaultIgnoredLoopCounterNames[] = "^[ijk_]$";
  20. const char DefaultIgnoredVariableNames[] = "";
  21. const char DefaultIgnoredExceptionVariableNames[] = "^[e]$";
  22. const char DefaultIgnoredParameterNames[] = "^[n]$";
  23. const char ErrorMessage[] =
  24. "%select{variable|exception variable|loop variable|"
  25. "parameter}0 name %1 is too short, expected at least %2 characters";
  26. IdentifierLengthCheck::IdentifierLengthCheck(StringRef Name,
  27. ClangTidyContext *Context)
  28. : ClangTidyCheck(Name, Context),
  29. MinimumVariableNameLength(Options.get("MinimumVariableNameLength",
  30. DefaultMinimumVariableNameLength)),
  31. MinimumLoopCounterNameLength(Options.get(
  32. "MinimumLoopCounterNameLength", DefaultMinimumLoopCounterNameLength)),
  33. MinimumExceptionNameLength(Options.get(
  34. "MinimumExceptionNameLength", DefaultMinimumExceptionNameLength)),
  35. MinimumParameterNameLength(Options.get(
  36. "MinimumParameterNameLength", DefaultMinimumParameterNameLength)),
  37. IgnoredVariableNamesInput(
  38. Options.get("IgnoredVariableNames", DefaultIgnoredVariableNames)),
  39. IgnoredVariableNames(IgnoredVariableNamesInput),
  40. IgnoredLoopCounterNamesInput(Options.get("IgnoredLoopCounterNames",
  41. DefaultIgnoredLoopCounterNames)),
  42. IgnoredLoopCounterNames(IgnoredLoopCounterNamesInput),
  43. IgnoredExceptionVariableNamesInput(
  44. Options.get("IgnoredExceptionVariableNames",
  45. DefaultIgnoredExceptionVariableNames)),
  46. IgnoredExceptionVariableNames(IgnoredExceptionVariableNamesInput),
  47. IgnoredParameterNamesInput(
  48. Options.get("IgnoredParameterNames", DefaultIgnoredParameterNames)),
  49. IgnoredParameterNames(IgnoredParameterNamesInput) {}
  50. void IdentifierLengthCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
  51. Options.store(Opts, "MinimumVariableNameLength", MinimumVariableNameLength);
  52. Options.store(Opts, "MinimumLoopCounterNameLength",
  53. MinimumLoopCounterNameLength);
  54. Options.store(Opts, "MinimumExceptionNameLength", MinimumExceptionNameLength);
  55. Options.store(Opts, "MinimumParameterNameLength", MinimumParameterNameLength);
  56. Options.store(Opts, "IgnoredLoopCounterNames", IgnoredLoopCounterNamesInput);
  57. Options.store(Opts, "IgnoredVariableNames", IgnoredVariableNamesInput);
  58. Options.store(Opts, "IgnoredExceptionVariableNames",
  59. IgnoredExceptionVariableNamesInput);
  60. Options.store(Opts, "IgnoredParameterNames", IgnoredParameterNamesInput);
  61. }
  62. void IdentifierLengthCheck::registerMatchers(MatchFinder *Finder) {
  63. if (MinimumLoopCounterNameLength > 1)
  64. Finder->addMatcher(
  65. forStmt(hasLoopInit(declStmt(forEach(varDecl().bind("loopVar"))))),
  66. this);
  67. if (MinimumExceptionNameLength > 1)
  68. Finder->addMatcher(varDecl(hasParent(cxxCatchStmt())).bind("exceptionVar"),
  69. this);
  70. if (MinimumParameterNameLength > 1)
  71. Finder->addMatcher(parmVarDecl().bind("paramVar"), this);
  72. if (MinimumVariableNameLength > 1)
  73. Finder->addMatcher(
  74. varDecl(unless(anyOf(hasParent(declStmt(hasParent(forStmt()))),
  75. hasParent(cxxCatchStmt()), parmVarDecl())))
  76. .bind("standaloneVar"),
  77. this);
  78. }
  79. void IdentifierLengthCheck::check(const MatchFinder::MatchResult &Result) {
  80. const auto *StandaloneVar = Result.Nodes.getNodeAs<VarDecl>("standaloneVar");
  81. if (StandaloneVar) {
  82. if (!StandaloneVar->getIdentifier())
  83. return;
  84. StringRef VarName = StandaloneVar->getName();
  85. if (VarName.size() >= MinimumVariableNameLength ||
  86. IgnoredVariableNames.match(VarName))
  87. return;
  88. diag(StandaloneVar->getLocation(), ErrorMessage)
  89. << 0 << StandaloneVar << MinimumVariableNameLength;
  90. }
  91. auto *ExceptionVarName = Result.Nodes.getNodeAs<VarDecl>("exceptionVar");
  92. if (ExceptionVarName) {
  93. if (!ExceptionVarName->getIdentifier())
  94. return;
  95. StringRef VarName = ExceptionVarName->getName();
  96. if (VarName.size() >= MinimumExceptionNameLength ||
  97. IgnoredExceptionVariableNames.match(VarName))
  98. return;
  99. diag(ExceptionVarName->getLocation(), ErrorMessage)
  100. << 1 << ExceptionVarName << MinimumExceptionNameLength;
  101. }
  102. const auto *LoopVar = Result.Nodes.getNodeAs<VarDecl>("loopVar");
  103. if (LoopVar) {
  104. if (!LoopVar->getIdentifier())
  105. return;
  106. StringRef VarName = LoopVar->getName();
  107. if (VarName.size() >= MinimumLoopCounterNameLength ||
  108. IgnoredLoopCounterNames.match(VarName))
  109. return;
  110. diag(LoopVar->getLocation(), ErrorMessage)
  111. << 2 << LoopVar << MinimumLoopCounterNameLength;
  112. }
  113. const auto *ParamVar = Result.Nodes.getNodeAs<VarDecl>("paramVar");
  114. if (ParamVar) {
  115. if (!ParamVar->getIdentifier())
  116. return;
  117. StringRef VarName = ParamVar->getName();
  118. if (VarName.size() >= MinimumParameterNameLength ||
  119. IgnoredParameterNames.match(VarName))
  120. return;
  121. diag(ParamVar->getLocation(), ErrorMessage)
  122. << 3 << ParamVar << MinimumParameterNameLength;
  123. }
  124. }
  125. } // namespace clang::tidy::readability