clang-tools 6.0.0

PropertyDeclarationCheck.cpp
Go to the documentation of this file.
1 //===--- PropertyDeclarationCheck.cpp - clang-tidy-------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "PropertyDeclarationCheck.h"
11 #include "../utils/OptionsUtils.h"
12 #include "clang/AST/ASTContext.h"
13 #include "clang/ASTMatchers/ASTMatchFinder.h"
14 #include "llvm/ADT/StringExtras.h"
15 #include "llvm/Support/Regex.h"
16 #include <algorithm>
17
18 using namespace clang::ast_matchers;
19
20 namespace clang {
21 namespace tidy {
22 namespace objc {
23
24 namespace {
25 /// The acronyms are from
26 /// https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CodingGuidelines/Articles/APIAbbreviations.html#//apple_ref/doc/uid/20001285-BCIHCGAE
27 constexpr char DefaultSpecialAcronyms[] =
28 "ASCII;"
29 "PDF;"
30 "XML;"
31 "HTML;"
32 "URL;"
33 "RTF;"
34 "HTTP;"
35 "TIFF;"
36 "JPG;"
37 "PNG;"
38 "GIF;"
39 "LZW;"
40 "ROM;"
41 "RGB;"
42 "CMYK;"
43 "MIDI;"
44 "FTP";
45
46 /// For now we will only fix 'CamelCase' property to
47 /// 'camelCase'. For other cases the users need to
48 /// come up with a proper name by their own.
49 /// FIXME: provide fix for snake_case to snakeCase
50 FixItHint generateFixItHint(const ObjCPropertyDecl *Decl) {
51 if (isupper(Decl->getName()[0])) {
52 auto NewName = Decl->getName().str();
53 NewName[0] = tolower(NewName[0]);
54 return FixItHint::CreateReplacement(
55 CharSourceRange::getTokenRange(SourceRange(Decl->getLocation())),
56 llvm::StringRef(NewName));
57 }
58 return FixItHint();
59 }
60
61 std::string validPropertyNameRegex(const std::vector<std::string> &Prefixes) {
62 std::vector<std::string> EscapedPrefixes;
63 EscapedPrefixes.reserve(Prefixes.size());
64 // In case someone defines a custom prefix which includes a regex
65 // special character, escape all the prefixes.
66 std::transform(Prefixes.begin(), Prefixes.end(),
67 std::back_inserter(EscapedPrefixes), [](const std::string& s) {
68 return llvm::Regex::escape(s); });
69 // Allow any of these names:
70 // foo
71 // fooBar
72 // url
73 // urlString
74 // URL
75 // URLString
76 return std::string("::((") +
77 llvm::join(EscapedPrefixes.begin(), EscapedPrefixes.end(), "|") +
78 ")[A-Z]?)?[a-z]+[a-z0-9]*([A-Z][a-z0-9]+)*$";
79 }
80 } // namespace
81
82 PropertyDeclarationCheck::PropertyDeclarationCheck(StringRef Name,
83 ClangTidyContext *Context)
84 : ClangTidyCheck(Name, Context),
85 SpecialAcronyms(utils::options::parseStringList(
86 Options.get("Acronyms", DefaultSpecialAcronyms))) {}
87
88 void PropertyDeclarationCheck::registerMatchers(MatchFinder *Finder) {
89 Finder->addMatcher(
90 objcPropertyDecl(
91 // the property name should be in Lower Camel Case like
92 // 'lowerCamelCase'
93 unless(matchesName(validPropertyNameRegex(SpecialAcronyms))))
94 .bind("property"),
95 this);
96 }
97
98 void PropertyDeclarationCheck::check(const MatchFinder::MatchResult &Result) {
99 const auto *MatchedDecl =
100 Result.Nodes.getNodeAs<ObjCPropertyDecl>("property");
101 assert(MatchedDecl->getName().size() > 0);
102 diag(MatchedDecl->getLocation(),
103 "property name '%0' should use lowerCamelCase style, according to "
104 "the Apple Coding Guidelines")
105 << MatchedDecl->getName() << generateFixItHint(MatchedDecl);
106 }
107
108 void PropertyDeclarationCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
109 Options.store(Opts, "Acronyms",
110 utils::options::serializeStringList(SpecialAcronyms));
111 }
112
113 } // namespace objc
114 } // namespace tidy
115 } // namespace clang
clang::ast_matchers
Definition: ClangTidyDiagnosticConsumer.h:27
clang::tidy::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: ClangTidy.cpp:449
clang::tidy::objc::PropertyDeclarationCheck::storeOptions
void storeOptions(ClangTidyOptions::OptionMap &Options) override
Should store all options supported by this check with their current values or default values for opti...
Definition: PropertyDeclarationCheck.cpp:108
clang::tidy::utils::options::serializeStringList
std::string serializeStringList(ArrayRef< std::string > Strings)
Serialize a sequence of names that can be parsed by parseStringList.
Definition: OptionsUtils.cpp:31
Name
StringHandle Name
Definition: PreprocessorTracker.cpp:525
clang::tidy::ClangTidyCheck
Base class for all clang-tidy checks.
Definition: ClangTidy.h:127
clang::tidy::utils::options::parseStringList
std::vector< std::string > parseStringList(StringRef Option)
Parse a semicolon separated list of strings.
Definition: OptionsUtils.cpp:19
clang::tidy::ClangTidyCheck::Options
OptionsView Options
Definition: ClangTidy.h:183
clang::tidy::ClangTidyOptions::OptionMap
std::map< std::string, std::string > OptionMap
Definition: ClangTidyOptions.h:99
clang
Definition: AndroidTidyModule.cpp:28
clang::tidy::ClangTidyContext
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
Definition: ClangTidyDiagnosticConsumer.h:104
clang::tidy::objc::PropertyDeclarationCheck::check
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
ClangTidyChecks that register ASTMatchers should do the actual work in here.
Definition: PropertyDeclarationCheck.cpp:98
clang::tidy::cppcoreguidelines::join
static std::string join(ArrayRef< SpecialMemberFunctionsCheck::SpecialMemberFunctionKind > SMFS, llvm::StringRef AndOr)
Definition: SpecialMemberFunctionsCheck.cpp:82
clang::tidy::objc::PropertyDeclarationCheck::registerMatchers
void registerMatchers(ast_matchers::MatchFinder *Finder) override
Override this to register AST matchers with Finder.
Definition: PropertyDeclarationCheck.cpp:88
clang::tidy::ClangTidyCheck::diag
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Add a diagnostic with the check&#39;s name.
Definition: ClangTidy.cpp:416
PropertyDeclarationCheck.h