diff options
Diffstat (limited to 'clang-tidy/objc')
-rw-r--r-- | clang-tidy/objc/AvoidNSErrorInitCheck.cpp | 7 | ||||
-rw-r--r-- | clang-tidy/objc/AvoidNSErrorInitCheck.h | 9 | ||||
-rw-r--r-- | clang-tidy/objc/AvoidSpinlockCheck.cpp | 7 | ||||
-rw-r--r-- | clang-tidy/objc/AvoidSpinlockCheck.h | 9 | ||||
-rw-r--r-- | clang-tidy/objc/CMakeLists.txt | 1 | ||||
-rw-r--r-- | clang-tidy/objc/ForbiddenSubclassingCheck.cpp | 7 | ||||
-rw-r--r-- | clang-tidy/objc/ForbiddenSubclassingCheck.h | 9 | ||||
-rw-r--r-- | clang-tidy/objc/ObjCTidyModule.cpp | 10 | ||||
-rw-r--r-- | clang-tidy/objc/PropertyDeclarationCheck.cpp | 40 | ||||
-rw-r--r-- | clang-tidy/objc/PropertyDeclarationCheck.h | 20 | ||||
-rw-r--r-- | clang-tidy/objc/SuperSelfCheck.cpp | 127 | ||||
-rw-r--r-- | clang-tidy/objc/SuperSelfCheck.h | 36 |
12 files changed, 209 insertions, 73 deletions
diff --git a/clang-tidy/objc/AvoidNSErrorInitCheck.cpp b/clang-tidy/objc/AvoidNSErrorInitCheck.cpp index d5e2027a..eb18dcd2 100644 --- a/clang-tidy/objc/AvoidNSErrorInitCheck.cpp +++ b/clang-tidy/objc/AvoidNSErrorInitCheck.cpp @@ -1,9 +1,8 @@ //===--- AvoidNSErrorInitCheck.cpp - clang-tidy----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/objc/AvoidNSErrorInitCheck.h b/clang-tidy/objc/AvoidNSErrorInitCheck.h index 379b8a2a..030a532e 100644 --- a/clang-tidy/objc/AvoidNSErrorInitCheck.h +++ b/clang-tidy/objc/AvoidNSErrorInitCheck.h @@ -1,16 +1,15 @@ //===--- AvoidNSErrorInitCheck.h - clang-tidy--------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_AVOIDNSERRORINITCHECK_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_AVOIDNSERRORINITCHECK_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tidy/objc/AvoidSpinlockCheck.cpp b/clang-tidy/objc/AvoidSpinlockCheck.cpp index 319d9456..ac3d2b28 100644 --- a/clang-tidy/objc/AvoidSpinlockCheck.cpp +++ b/clang-tidy/objc/AvoidSpinlockCheck.cpp @@ -1,9 +1,8 @@ //===--- AvoidSpinlockCheck.cpp - clang-tidy-------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/objc/AvoidSpinlockCheck.h b/clang-tidy/objc/AvoidSpinlockCheck.h index d9dbf8cb..dd409625 100644 --- a/clang-tidy/objc/AvoidSpinlockCheck.h +++ b/clang-tidy/objc/AvoidSpinlockCheck.h @@ -1,16 +1,15 @@ //===--- AvoidSpinlockCheck.h - clang-tidy-----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_AVOID_SPINLOCK_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_AVOID_SPINLOCK_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tidy/objc/CMakeLists.txt b/clang-tidy/objc/CMakeLists.txt index 4063bba1..4eeb1484 100644 --- a/clang-tidy/objc/CMakeLists.txt +++ b/clang-tidy/objc/CMakeLists.txt @@ -6,6 +6,7 @@ add_clang_library(clangTidyObjCModule ForbiddenSubclassingCheck.cpp ObjCTidyModule.cpp PropertyDeclarationCheck.cpp + SuperSelfCheck.cpp LINK_LIBS clangAST diff --git a/clang-tidy/objc/ForbiddenSubclassingCheck.cpp b/clang-tidy/objc/ForbiddenSubclassingCheck.cpp index 0599b21d..6b8e7951 100644 --- a/clang-tidy/objc/ForbiddenSubclassingCheck.cpp +++ b/clang-tidy/objc/ForbiddenSubclassingCheck.cpp @@ -1,9 +1,8 @@ //===--- ForbiddenSubclassingCheck.cpp - clang-tidy -----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/objc/ForbiddenSubclassingCheck.h b/clang-tidy/objc/ForbiddenSubclassingCheck.h index 6c7e08b3..c05ba084 100644 --- a/clang-tidy/objc/ForbiddenSubclassingCheck.h +++ b/clang-tidy/objc/ForbiddenSubclassingCheck.h @@ -1,16 +1,15 @@ //===--- ForbiddenSubclassingCheck.h - clang-tidy ---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_FORBIDDEN_SUBCLASSING_CHECK_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_FORBIDDEN_SUBCLASSING_CHECK_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" #include "llvm/ADT/StringRef.h" #include <string> #include <vector> diff --git a/clang-tidy/objc/ObjCTidyModule.cpp b/clang-tidy/objc/ObjCTidyModule.cpp index 19152c21..636e2c02 100644 --- a/clang-tidy/objc/ObjCTidyModule.cpp +++ b/clang-tidy/objc/ObjCTidyModule.cpp @@ -1,9 +1,8 @@ //===--- ObjCTidyModule.cpp - clang-tidy --------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -14,6 +13,7 @@ #include "AvoidSpinlockCheck.h" #include "ForbiddenSubclassingCheck.h" #include "PropertyDeclarationCheck.h" +#include "SuperSelfCheck.h" using namespace clang::ast_matchers; @@ -32,6 +32,8 @@ public: "objc-forbidden-subclassing"); CheckFactories.registerCheck<PropertyDeclarationCheck>( "objc-property-declaration"); + CheckFactories.registerCheck<SuperSelfCheck>( + "objc-super-self"); } }; diff --git a/clang-tidy/objc/PropertyDeclarationCheck.cpp b/clang-tidy/objc/PropertyDeclarationCheck.cpp index 94b82f00..094c193c 100644 --- a/clang-tidy/objc/PropertyDeclarationCheck.cpp +++ b/clang-tidy/objc/PropertyDeclarationCheck.cpp @@ -1,9 +1,8 @@ //===--- PropertyDeclarationCheck.cpp - clang-tidy-------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -81,7 +80,8 @@ std::string validPropertyNameRegex(bool UsedInMatcher) { } bool hasCategoryPropertyPrefix(llvm::StringRef PropertyName) { - auto RegexExp = llvm::Regex("^[a-zA-Z]+_[a-zA-Z0-9][a-zA-Z0-9_]+$"); + auto RegexExp = + llvm::Regex("^[a-zA-Z][a-zA-Z0-9]*_[a-zA-Z0-9][a-zA-Z0-9_]+$"); return RegexExp.match(PropertyName); } @@ -92,31 +92,21 @@ bool prefixedPropertyNameValid(llvm::StringRef PropertyName) { if (Prefix.lower() != Prefix) { return false; } - auto RegexExp = - llvm::Regex(llvm::StringRef(validPropertyNameRegex(false))); + auto RegexExp = llvm::Regex(llvm::StringRef(validPropertyNameRegex(false))); return RegexExp.match(PropertyName.substr(Start + 1)); } } // namespace -PropertyDeclarationCheck::PropertyDeclarationCheck(StringRef Name, - ClangTidyContext *Context) - : ClangTidyCheck(Name, Context), - SpecialAcronyms( - utils::options::parseStringList(Options.get("Acronyms", ""))), - IncludeDefaultAcronyms(Options.get("IncludeDefaultAcronyms", true)), - EscapedAcronyms() {} - void PropertyDeclarationCheck::registerMatchers(MatchFinder *Finder) { // this check should only be applied to ObjC sources. if (!getLangOpts().ObjC) return; - Finder->addMatcher( - objcPropertyDecl( - // the property name should be in Lower Camel Case like - // 'lowerCamelCase' - unless(matchesName(validPropertyNameRegex(true)))) - .bind("property"), - this); + Finder->addMatcher(objcPropertyDecl( + // the property name should be in Lower Camel Case like + // 'lowerCamelCase' + unless(matchesName(validPropertyNameRegex(true)))) + .bind("property"), + this); } void PropertyDeclarationCheck::check(const MatchFinder::MatchResult &Result) { @@ -146,12 +136,6 @@ void PropertyDeclarationCheck::check(const MatchFinder::MatchResult &Result) { << generateFixItHint(MatchedDecl, StandardProperty); } -void PropertyDeclarationCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { - Options.store(Opts, "Acronyms", - utils::options::serializeStringList(SpecialAcronyms)); - Options.store(Opts, "IncludeDefaultAcronyms", IncludeDefaultAcronyms); -} - } // namespace objc } // namespace tidy } // namespace clang diff --git a/clang-tidy/objc/PropertyDeclarationCheck.h b/clang-tidy/objc/PropertyDeclarationCheck.h index b2683bae..769f0c4c 100644 --- a/clang-tidy/objc/PropertyDeclarationCheck.h +++ b/clang-tidy/objc/PropertyDeclarationCheck.h @@ -1,18 +1,15 @@ //===--- PropertyDeclarationCheck.h - clang-tidy-----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_PROPERTY_DECLARATION_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_PROPERTY_DECLARATION_H -#include "../ClangTidy.h" -#include <string> -#include <vector> +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { @@ -28,15 +25,10 @@ namespace objc { /// http://clang.llvm.org/extra/clang-tidy/checks/objc-property-declaration.html class PropertyDeclarationCheck : public ClangTidyCheck { public: - PropertyDeclarationCheck(StringRef Name, ClangTidyContext *Context); + PropertyDeclarationCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; - void storeOptions(ClangTidyOptions::OptionMap &Options) override; - -private: - const std::vector<std::string> SpecialAcronyms; - const bool IncludeDefaultAcronyms; - std::vector<std::string> EscapedAcronyms; }; } // namespace objc diff --git a/clang-tidy/objc/SuperSelfCheck.cpp b/clang-tidy/objc/SuperSelfCheck.cpp new file mode 100644 index 00000000..7aafd66a --- /dev/null +++ b/clang-tidy/objc/SuperSelfCheck.cpp @@ -0,0 +1,127 @@ +//===--- SuperSelfCheck.cpp - clang-tidy ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "SuperSelfCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace objc { + +namespace { + +/// \brief Matches Objective-C methods in the initializer family. +/// +/// Example matches -init and -initWithInt:. +/// (matcher = objcMethodDecl(isInitializer())) +/// \code +/// @interface Foo +/// - (instancetype)init; +/// - (instancetype)initWithInt:(int)i; +/// + (instancetype)init; +/// - (void)bar; +/// @end +/// \endcode +AST_MATCHER(ObjCMethodDecl, isInitializer) { + return Node.getMethodFamily() == OMF_init; +} + +/// \brief Matches Objective-C implementations of classes that directly or +/// indirectly have a superclass matching \c InterfaceDecl. +/// +/// Note that a class is not considered to be a subclass of itself. +/// +/// Example matches implementation declarations for Y and Z. +/// (matcher = objcInterfaceDecl(isSubclassOf(hasName("X")))) +/// \code +/// @interface X +/// @end +/// @interface Y : X +/// @end +/// @implementation Y // directly derived +/// @end +/// @interface Z : Y +/// @end +/// @implementation Z // indirectly derived +/// @end +/// \endcode +AST_MATCHER_P(ObjCImplementationDecl, isSubclassOf, + ast_matchers::internal::Matcher<ObjCInterfaceDecl>, + InterfaceDecl) { + // Check if any of the superclasses of the class match. + for (const ObjCInterfaceDecl *SuperClass = + Node.getClassInterface()->getSuperClass(); + SuperClass != nullptr; SuperClass = SuperClass->getSuperClass()) { + if (InterfaceDecl.matches(*SuperClass, Finder, Builder)) + return true; + } + + // No matches found. + return false; +} + +/// \brief Matches Objective-C message expressions where the receiver is the +/// super instance. +/// +/// Example matches the invocations of -banana and -orange. +/// (matcher = objcMessageExpr(isMessagingSuperInstance())) +/// \code +/// - (void)banana { +/// [self apple] +/// [super banana]; +/// [super orange]; +/// } +/// \endcode +AST_MATCHER(ObjCMessageExpr, isMessagingSuperInstance) { + return Node.getReceiverKind() == ObjCMessageExpr::SuperInstance; +} + +} // namespace + +void SuperSelfCheck::registerMatchers(MatchFinder *Finder) { + // This check should only be applied to Objective-C sources. + if (!getLangOpts().ObjC) + return; + + Finder->addMatcher( + objcMessageExpr( + hasSelector("self"), isMessagingSuperInstance(), + hasAncestor(objcMethodDecl(isInitializer(), + hasDeclContext(objcImplementationDecl( + isSubclassOf(hasName("NSObject"))))))) + .bind("message"), + this); +} + +void SuperSelfCheck::check(const MatchFinder::MatchResult &Result) { + const auto *Message = Result.Nodes.getNodeAs<ObjCMessageExpr>("message"); + + auto Diag = diag(Message->getExprLoc(), "suspicious invocation of %0 in " + "initializer; did you mean to " + "invoke a superclass initializer?") + << Message->getMethodDecl(); + + SourceLocation ReceiverLoc = Message->getReceiverRange().getBegin(); + if (ReceiverLoc.isMacroID() || ReceiverLoc.isInvalid()) + return; + + SourceLocation SelectorLoc = Message->getSelectorStartLoc(); + if (SelectorLoc.isMacroID() || SelectorLoc.isInvalid()) + return; + + Diag << FixItHint::CreateReplacement(Message->getSourceRange(), + StringRef("[super init]")); +} + +} // namespace objc +} // namespace tidy +} // namespace clang diff --git a/clang-tidy/objc/SuperSelfCheck.h b/clang-tidy/objc/SuperSelfCheck.h new file mode 100644 index 00000000..ed5d1cd0 --- /dev/null +++ b/clang-tidy/objc/SuperSelfCheck.h @@ -0,0 +1,36 @@ +//===--- SuperSelfCheck.h - clang-tidy --------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_SUPERSELFCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_SUPERSELFCHECK_H + +#include "../ClangTidy.h" + +namespace clang { +namespace tidy { +namespace objc { + +/// Finds invocations of -self on super instances in initializers of subclasses +/// of NSObject and recommends calling a superclass initializer instead. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/objc-super-self.html +class SuperSelfCheck : public ClangTidyCheck { +public: + SuperSelfCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; +}; + +} // namespace objc +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_SUPERSELFCHECK_H |