150
|
1 //===--- IdentifierNamingCheck.h - clang-tidy -------------------*- C++ -*-===//
|
|
2 //
|
|
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
4 // See https://llvm.org/LICENSE.txt for license information.
|
|
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
6 //
|
|
7 //===----------------------------------------------------------------------===//
|
|
8
|
|
9 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IDENTIFIERNAMINGCHECK_H
|
|
10 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IDENTIFIERNAMINGCHECK_H
|
|
11
|
|
12 #include "../utils/RenamerClangTidyCheck.h"
|
221
|
13 #include "llvm/ADT/Optional.h"
|
150
|
14 namespace clang {
|
|
15 namespace tidy {
|
|
16 namespace readability {
|
|
17
|
236
|
18 enum StyleKind : int;
|
|
19
|
150
|
20 /// Checks for identifiers naming style mismatch.
|
|
21 ///
|
|
22 /// This check will try to enforce coding guidelines on the identifiers naming.
|
|
23 /// It supports `lower_case`, `UPPER_CASE`, `camelBack` and `CamelCase` casing
|
|
24 /// and tries to convert from one to another if a mismatch is detected.
|
|
25 ///
|
|
26 /// It also supports a fixed prefix and suffix that will be prepended or
|
|
27 /// appended to the identifiers, regardless of the casing.
|
|
28 ///
|
|
29 /// Many configuration options are available, in order to be able to create
|
|
30 /// different rules for different kind of identifier. In general, the
|
|
31 /// rules are falling back to a more generic rule if the specific case is not
|
|
32 /// configured.
|
|
33 class IdentifierNamingCheck final : public RenamerClangTidyCheck {
|
|
34 public:
|
|
35 IdentifierNamingCheck(StringRef Name, ClangTidyContext *Context);
|
|
36 ~IdentifierNamingCheck();
|
|
37
|
|
38 void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
|
|
39
|
|
40 enum CaseType {
|
|
41 CT_AnyCase = 0,
|
|
42 CT_LowerCase,
|
|
43 CT_CamelBack,
|
|
44 CT_UpperCase,
|
|
45 CT_CamelCase,
|
|
46 CT_CamelSnakeCase,
|
|
47 CT_CamelSnakeBack
|
|
48 };
|
|
49
|
236
|
50 enum HungarianPrefixType {
|
|
51 HPT_Off = 0,
|
|
52 HPT_On,
|
|
53 HPT_LowerCase,
|
|
54 HPT_CamelCase,
|
|
55 };
|
|
56
|
|
57 struct HungarianNotationOption {
|
|
58 HungarianNotationOption() : HPType(HungarianPrefixType::HPT_Off) {}
|
|
59
|
|
60 llvm::Optional<CaseType> Case;
|
|
61 HungarianPrefixType HPType;
|
|
62 llvm::StringMap<std::string> General;
|
|
63 llvm::StringMap<std::string> CString;
|
|
64 llvm::StringMap<std::string> PrimitiveType;
|
|
65 llvm::StringMap<std::string> UserDefinedType;
|
|
66 llvm::StringMap<std::string> DerivedType;
|
|
67 };
|
|
68
|
150
|
69 struct NamingStyle {
|
|
70 NamingStyle() = default;
|
|
71
|
|
72 NamingStyle(llvm::Optional<CaseType> Case, const std::string &Prefix,
|
236
|
73 const std::string &Suffix, const std::string &IgnoredRegexpStr,
|
|
74 HungarianPrefixType HPType);
|
221
|
75 NamingStyle(const NamingStyle &O) = delete;
|
|
76 NamingStyle &operator=(NamingStyle &&O) = default;
|
|
77 NamingStyle(NamingStyle &&O) = default;
|
150
|
78
|
|
79 llvm::Optional<CaseType> Case;
|
|
80 std::string Prefix;
|
|
81 std::string Suffix;
|
221
|
82 // Store both compiled and non-compiled forms so original value can be
|
|
83 // serialized
|
|
84 llvm::Regex IgnoredRegexp;
|
|
85 std::string IgnoredRegexpStr;
|
236
|
86
|
|
87 HungarianPrefixType HPType;
|
|
88 };
|
|
89
|
|
90 struct HungarianNotation {
|
|
91 public:
|
|
92 bool checkOptionValid(int StyleKindIndex) const;
|
|
93 bool isOptionEnabled(StringRef OptionKey,
|
|
94 const llvm::StringMap<std::string> &StrMap) const;
|
|
95 void loadDefaultConfig(
|
|
96 IdentifierNamingCheck::HungarianNotationOption &HNOption) const;
|
|
97 void loadFileConfig(
|
|
98 const ClangTidyCheck::OptionsView &Options,
|
|
99 IdentifierNamingCheck::HungarianNotationOption &HNOption) const;
|
|
100
|
|
101 bool removeDuplicatedPrefix(
|
|
102 SmallVector<StringRef, 8> &Words,
|
|
103 const IdentifierNamingCheck::HungarianNotationOption &HNOption) const;
|
|
104
|
|
105 std::string getPrefix(
|
|
106 const Decl *D,
|
|
107 const IdentifierNamingCheck::HungarianNotationOption &HNOption) const;
|
|
108
|
|
109 std::string getDataTypePrefix(
|
|
110 StringRef TypeName, const NamedDecl *ND,
|
|
111 const IdentifierNamingCheck::HungarianNotationOption &HNOption) const;
|
|
112
|
|
113 std::string getClassPrefix(
|
|
114 const CXXRecordDecl *CRD,
|
|
115 const IdentifierNamingCheck::HungarianNotationOption &HNOption) const;
|
|
116
|
|
117 std::string getEnumPrefix(const EnumConstantDecl *ECD) const;
|
|
118 std::string getDeclTypeName(const NamedDecl *ND) const;
|
221
|
119 };
|
|
120
|
|
121 struct FileStyle {
|
|
122 FileStyle() : IsActive(false), IgnoreMainLikeFunctions(false) {}
|
|
123 FileStyle(SmallVectorImpl<Optional<NamingStyle>> &&Styles,
|
236
|
124 HungarianNotationOption HNOption, bool IgnoreMainLike)
|
|
125 : Styles(std::move(Styles)), HNOption(std::move(HNOption)),
|
|
126 IsActive(true), IgnoreMainLikeFunctions(IgnoreMainLike) {}
|
221
|
127
|
|
128 ArrayRef<Optional<NamingStyle>> getStyles() const {
|
|
129 assert(IsActive);
|
|
130 return Styles;
|
|
131 }
|
236
|
132
|
|
133 const HungarianNotationOption &getHNOption() const {
|
|
134 assert(IsActive);
|
|
135 return HNOption;
|
|
136 }
|
|
137
|
221
|
138 bool isActive() const { return IsActive; }
|
|
139 bool isIgnoringMainLikeFunction() const { return IgnoreMainLikeFunctions; }
|
|
140
|
|
141 private:
|
|
142 SmallVector<Optional<NamingStyle>, 0> Styles;
|
236
|
143 HungarianNotationOption HNOption;
|
221
|
144 bool IsActive;
|
|
145 bool IgnoreMainLikeFunctions;
|
150
|
146 };
|
|
147
|
236
|
148 IdentifierNamingCheck::FileStyle
|
|
149 getFileStyleFromOptions(const ClangTidyCheck::OptionsView &Options) const;
|
|
150
|
|
151 bool
|
|
152 matchesStyle(StringRef Type, StringRef Name,
|
|
153 const IdentifierNamingCheck::NamingStyle &Style,
|
|
154 const IdentifierNamingCheck::HungarianNotationOption &HNOption,
|
|
155 const NamedDecl *Decl) const;
|
|
156
|
|
157 std::string
|
|
158 fixupWithCase(StringRef Type, StringRef Name, const Decl *D,
|
|
159 const IdentifierNamingCheck::NamingStyle &Style,
|
|
160 const IdentifierNamingCheck::HungarianNotationOption &HNOption,
|
|
161 IdentifierNamingCheck::CaseType Case) const;
|
|
162
|
|
163 std::string
|
|
164 fixupWithStyle(StringRef Type, StringRef Name,
|
|
165 const IdentifierNamingCheck::NamingStyle &Style,
|
|
166 const IdentifierNamingCheck::HungarianNotationOption &HNOption,
|
|
167 const Decl *D) const;
|
|
168
|
|
169 StyleKind findStyleKind(
|
|
170 const NamedDecl *D,
|
|
171 ArrayRef<llvm::Optional<IdentifierNamingCheck::NamingStyle>> NamingStyles,
|
|
172 bool IgnoreMainLikeFunctions) const;
|
|
173
|
|
174 llvm::Optional<RenamerClangTidyCheck::FailureInfo> getFailureInfo(
|
|
175 StringRef Type, StringRef Name, const NamedDecl *ND,
|
|
176 SourceLocation Location,
|
|
177 ArrayRef<llvm::Optional<IdentifierNamingCheck::NamingStyle>> NamingStyles,
|
|
178 const IdentifierNamingCheck::HungarianNotationOption &HNOption,
|
|
179 StyleKind SK, const SourceManager &SM, bool IgnoreFailedSplit) const;
|
|
180
|
|
181 bool isParamInMainLikeFunction(const ParmVarDecl &ParmDecl,
|
|
182 bool IncludeMainLike) const;
|
|
183
|
150
|
184 private:
|
|
185 llvm::Optional<FailureInfo>
|
236
|
186 getDeclFailureInfo(const NamedDecl *Decl,
|
150
|
187 const SourceManager &SM) const override;
|
|
188 llvm::Optional<FailureInfo>
|
236
|
189 getMacroFailureInfo(const Token &MacroNameTok,
|
150
|
190 const SourceManager &SM) const override;
|
236
|
191 DiagInfo getDiagInfo(const NamingCheckId &ID,
|
150
|
192 const NamingCheckFailure &Failure) const override;
|
|
193
|
221
|
194 const FileStyle &getStyleForFile(StringRef FileName) const;
|
|
195
|
|
196 /// Stores the style options as a vector, indexed by the specified \ref
|
|
197 /// StyleKind, for a given directory.
|
|
198 mutable llvm::StringMap<FileStyle> NamingStylesCache;
|
|
199 FileStyle *MainFileStyle;
|
236
|
200 ClangTidyContext *Context;
|
|
201 const StringRef CheckName;
|
221
|
202 const bool GetConfigPerFile;
|
150
|
203 const bool IgnoreFailedSplit;
|
236
|
204 HungarianNotation HungarianNotation;
|
150
|
205 };
|
|
206
|
|
207 } // namespace readability
|
221
|
208 template <>
|
|
209 struct OptionEnumMapping<readability::IdentifierNamingCheck::CaseType> {
|
|
210 static llvm::ArrayRef<
|
|
211 std::pair<readability::IdentifierNamingCheck::CaseType, StringRef>>
|
|
212 getEnumMapping();
|
|
213 };
|
150
|
214 } // namespace tidy
|
|
215 } // namespace clang
|
|
216
|
|
217 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IDENTIFIERNAMINGCHECK_H
|