236
|
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
|
|
21 const unsigned DefaultMinimumVariableNameLength = 3;
|
|
22 const unsigned DefaultMinimumLoopCounterNameLength = 2;
|
|
23 const unsigned DefaultMinimumExceptionNameLength = 2;
|
|
24 const unsigned DefaultMinimumParameterNameLength = 3;
|
|
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",
|
|
38 DefaultMinimumVariableNameLength)),
|
|
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",
|
|
49 DefaultIgnoredLoopCounterNames)),
|
|
50 IgnoredLoopCounterNames(IgnoredLoopCounterNamesInput),
|
|
51 IgnoredExceptionVariableNamesInput(
|
|
52 Options.get("IgnoredExceptionVariableNames",
|
|
53 DefaultIgnoredExceptionVariableNames)),
|
|
54 IgnoredExceptionVariableNames(IgnoredExceptionVariableNamesInput),
|
|
55 IgnoredParameterNamesInput(
|
|
56 Options.get("IgnoredParameterNames", DefaultIgnoredParameterNames)),
|
|
57 IgnoredParameterNames(IgnoredParameterNamesInput) {}
|
|
58
|
|
59 void IdentifierLengthCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
|
|
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
|