clang-tools  14.0.0git
IdentifierLengthCheck.cpp
Go to the documentation of this file.
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 
10 #include "IdentifierLengthCheck.h"
11 #include "../utils/OptionsUtils.h"
12 #include "clang/AST/ASTContext.h"
13 #include "clang/ASTMatchers/ASTMatchFinder.h"
14 
15 using namespace clang::ast_matchers;
16 
17 namespace clang {
18 namespace tidy {
19 namespace readability {
20 
25 const char DefaultIgnoredLoopCounterNames[] = "^[ijk_]$";
26 const char DefaultIgnoredVariableNames[] = "";
27 const char DefaultIgnoredExceptionVariableNames[] = "^[e]$";
28 const char DefaultIgnoredParameterNames[] = "^[n]$";
29 
30 const char ErrorMessage[] =
31  "%select{variable|exception variable|loop variable|"
32  "parameter}0 name %1 is too short, expected at least %2 characters";
33 
34 IdentifierLengthCheck::IdentifierLengthCheck(StringRef Name,
35  ClangTidyContext *Context)
36  : ClangTidyCheck(Name, Context),
37  MinimumVariableNameLength(Options.get("MinimumVariableNameLength",
39  MinimumLoopCounterNameLength(Options.get(
40  "MinimumLoopCounterNameLength", DefaultMinimumLoopCounterNameLength)),
41  MinimumExceptionNameLength(Options.get(
42  "MinimumExceptionNameLength", DefaultMinimumExceptionNameLength)),
43  MinimumParameterNameLength(Options.get(
44  "MinimumParameterNameLength", DefaultMinimumParameterNameLength)),
45  IgnoredVariableNamesInput(
46  Options.get("IgnoredVariableNames", DefaultIgnoredVariableNames)),
47  IgnoredVariableNames(IgnoredVariableNamesInput),
48  IgnoredLoopCounterNamesInput(Options.get("IgnoredLoopCounterNames",
50  IgnoredLoopCounterNames(IgnoredLoopCounterNamesInput),
51  IgnoredExceptionVariableNamesInput(
52  Options.get("IgnoredExceptionVariableNames",
54  IgnoredExceptionVariableNames(IgnoredExceptionVariableNamesInput),
55  IgnoredParameterNamesInput(
56  Options.get("IgnoredParameterNames", DefaultIgnoredParameterNames)),
57  IgnoredParameterNames(IgnoredParameterNamesInput) {}
58 
60  Options.store(Opts, "MinimumVariableNameLength", MinimumVariableNameLength);
61  Options.store(Opts, "MinimumLoopCounterNameLength",
62  MinimumLoopCounterNameLength);
63  Options.store(Opts, "MinimumExceptionNameLength", MinimumExceptionNameLength);
64  Options.store(Opts, "MinimumParameterNameLength", MinimumParameterNameLength);
65  Options.store(Opts, "IgnoredLoopCounterNames", IgnoredLoopCounterNamesInput);
66  Options.store(Opts, "IgnoredVariableNames", IgnoredVariableNamesInput);
67  Options.store(Opts, "IgnoredExceptionVariableNames",
68  IgnoredExceptionVariableNamesInput);
69  Options.store(Opts, "IgnoredParameterNames", IgnoredParameterNamesInput);
70 }
71 
72 void IdentifierLengthCheck::registerMatchers(MatchFinder *Finder) {
73  if (MinimumLoopCounterNameLength > 1)
74  Finder->addMatcher(
75  forStmt(hasLoopInit(declStmt(forEach(varDecl().bind("loopVar"))))),
76  this);
77 
78  if (MinimumExceptionNameLength > 1)
79  Finder->addMatcher(varDecl(hasParent(cxxCatchStmt())).bind("exceptionVar"),
80  this);
81 
82  if (MinimumParameterNameLength > 1)
83  Finder->addMatcher(parmVarDecl().bind("paramVar"), this);
84 
85  if (MinimumVariableNameLength > 1)
86  Finder->addMatcher(
87  varDecl(unless(anyOf(hasParent(declStmt(hasParent(forStmt()))),
88  hasParent(cxxCatchStmt()), parmVarDecl())))
89  .bind("standaloneVar"),
90  this);
91 }
92 
93 void IdentifierLengthCheck::check(const MatchFinder::MatchResult &Result) {
94  const auto *StandaloneVar = Result.Nodes.getNodeAs<VarDecl>("standaloneVar");
95  if (StandaloneVar) {
96  if (!StandaloneVar->getIdentifier())
97  return;
98 
99  StringRef VarName = StandaloneVar->getName();
100 
101  if (VarName.size() >= MinimumVariableNameLength ||
102  IgnoredVariableNames.match(VarName))
103  return;
104 
105  diag(StandaloneVar->getLocation(), ErrorMessage)
106  << 0 << StandaloneVar << MinimumVariableNameLength;
107  }
108 
109  auto *ExceptionVarName = Result.Nodes.getNodeAs<VarDecl>("exceptionVar");
110  if (ExceptionVarName) {
111  if (!ExceptionVarName->getIdentifier())
112  return;
113 
114  StringRef VarName = ExceptionVarName->getName();
115  if (VarName.size() >= MinimumExceptionNameLength ||
116  IgnoredExceptionVariableNames.match(VarName))
117  return;
118 
119  diag(ExceptionVarName->getLocation(), ErrorMessage)
120  << 1 << ExceptionVarName << MinimumExceptionNameLength;
121  }
122 
123  const auto *LoopVar = Result.Nodes.getNodeAs<VarDecl>("loopVar");
124  if (LoopVar) {
125  if (!LoopVar->getIdentifier())
126  return;
127 
128  StringRef VarName = LoopVar->getName();
129 
130  if (VarName.size() >= MinimumLoopCounterNameLength ||
131  IgnoredLoopCounterNames.match(VarName))
132  return;
133 
134  diag(LoopVar->getLocation(), ErrorMessage)
135  << 2 << LoopVar << MinimumLoopCounterNameLength;
136  }
137 
138  const auto *ParamVar = Result.Nodes.getNodeAs<VarDecl>("paramVar");
139  if (ParamVar) {
140  if (!ParamVar->getIdentifier())
141  return;
142 
143  StringRef VarName = ParamVar->getName();
144 
145  if (VarName.size() >= MinimumParameterNameLength ||
146  IgnoredParameterNames.match(VarName))
147  return;
148 
149  diag(ParamVar->getLocation(), ErrorMessage)
150  << 3 << ParamVar << MinimumParameterNameLength;
151  }
152 }
153 
154 } // namespace readability
155 } // namespace tidy
156 } // namespace clang
clang::tidy::ClangTidyOptions::OptionMap
llvm::StringMap< ClangTidyValue > OptionMap
Definition: ClangTidyOptions.h:115
clang::tidy::readability::DefaultMinimumLoopCounterNameLength
const unsigned DefaultMinimumLoopCounterNameLength
Definition: IdentifierLengthCheck.cpp:22
clang::tidy::readability::DefaultMinimumExceptionNameLength
const unsigned DefaultMinimumExceptionNameLength
Definition: IdentifierLengthCheck.cpp:23
clang::tidy::readability::IdentifierLengthCheck::registerMatchers
void registerMatchers(ast_matchers::MatchFinder *Finder) override
Override this to register AST matchers with Finder.
Definition: IdentifierLengthCheck.cpp:72
clang::tidy::ClangTidyCheck
Base class for all clang-tidy checks.
Definition: ClangTidyCheck.h:54
clang::tidy::readability::DefaultMinimumParameterNameLength
const unsigned DefaultMinimumParameterNameLength
Definition: IdentifierLengthCheck.cpp:24
clang::tidy::readability::DefaultMinimumVariableNameLength
const unsigned DefaultMinimumVariableNameLength
Definition: IdentifierLengthCheck.cpp:21
clang::tidy::readability::IdentifierLengthCheck::storeOptions
void storeOptions(ClangTidyOptions::OptionMap &Opts) override
Should store all options supported by this check with their current values or default values for opti...
Definition: IdentifierLengthCheck.cpp:59
clang::tidy::readability::DefaultIgnoredVariableNames
const char DefaultIgnoredVariableNames[]
Definition: IdentifierLengthCheck.cpp:26
clang::ast_matchers
Definition: AbseilMatcher.h:14
IdentifierLengthCheck.h
clang::tidy::ClangTidyCheck::Options
OptionsView Options
Definition: ClangTidyCheck.h:416
DefaultIgnoredParameterNames
static const std::string DefaultIgnoredParameterNames
The default value for ignored parameter names.
Definition: EasilySwappableParametersCheck.cpp:26
clang::tidy::ClangTidyContext
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
Definition: ClangTidyDiagnosticConsumer.h:72
Name
static constexpr llvm::StringLiteral Name
Definition: UppercaseLiteralSuffixCheck.cpp:28
clang::tidy::readability::IdentifierLengthCheck::check
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
ClangTidyChecks that register ASTMatchers should do the actual work in here.
Definition: IdentifierLengthCheck.cpp:93
clang::tidy::readability::DefaultIgnoredLoopCounterNames
const char DefaultIgnoredLoopCounterNames[]
Definition: IdentifierLengthCheck.cpp:25
clang::tidy::ClangTidyCheck::diag
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Add a diagnostic with the check's name.
Definition: ClangTidyCheck.cpp:25
clang::tidy::readability::DefaultIgnoredExceptionVariableNames
const char DefaultIgnoredExceptionVariableNames[]
Definition: IdentifierLengthCheck.cpp:27
clang::tidy::readability::ErrorMessage
const char ErrorMessage[]
Definition: IdentifierLengthCheck.cpp:30
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
clang::tidy::ClangTidyCheck::OptionsView::store
void store(ClangTidyOptions::OptionMap &Options, StringRef LocalName, StringRef Value) const
Stores an option with the check-local name LocalName with string value Value to Options.
Definition: ClangTidyCheck.cpp:120