Wizard updated this revision to Diff 122552.
Wizard marked 9 inline comments as done.
Wizard added a comment.

add custom options


https://reviews.llvm.org/D39829

Files:
  clang-tidy/objc/CMakeLists.txt
  clang-tidy/objc/ObjCTidyModule.cpp
  clang-tidy/objc/PropertyDeclarationCheck.cpp
  clang-tidy/objc/PropertyDeclarationCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/google-objc-global-variable-declaration.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/objc-property-declaration.rst
  test/clang-tidy/objc-property-declaration-custom.m
  test/clang-tidy/objc-property-declaration.m

Index: test/clang-tidy/objc-property-declaration.m
===================================================================
--- /dev/null
+++ test/clang-tidy/objc-property-declaration.m
@@ -0,0 +1,10 @@
+// RUN: %check_clang_tidy %s objc-property-declaration %t
+@class NSString;
+
+@interface Foo
+@property(assign, nonatomic) int NotCamelCase;
+// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: property 'NotCamelCase' is not in proper format according to property naming convention. It should be in the format of lowerCamelCase or has special acronyms [objc-property-declaration]
+// CHECK-FIXES: @property(assign, nonatomic) int notCamelCase;
+@property(assign, nonatomic) int camelCase;
+@property(strong, nonatomic) NSString *URLString;
+@end
Index: test/clang-tidy/objc-property-declaration-custom.m
===================================================================
--- /dev/null
+++ test/clang-tidy/objc-property-declaration-custom.m
@@ -0,0 +1,11 @@
+// RUN: %check_clang_tidy %s objc-property-declaration %t \
+// RUN: -config='{CheckOptions: \
+// RUN:  [{key: objc-property-declaration.Acronyms, value: "ABC;TGIF"}]}' \
+// RUN: --
+
+@interface Foo
+@property(assign, nonatomic) int AbcNotRealPrefix;
+// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: property 'AbcNotRealPrefix' is not in proper format according to property naming convention. It should be in the format of lowerCamelCase or has special acronyms [objc-property-declaration]
+// CHECK-FIXES: @property(assign, nonatomic) int abcNotRealPrefix;
+@property(assign, nonatomic) int ABCCustomPrefix;
+@end
Index: docs/clang-tidy/checks/objc-property-declaration.rst
===================================================================
--- /dev/null
+++ docs/clang-tidy/checks/objc-property-declaration.rst
@@ -0,0 +1,43 @@
+.. title:: clang-tidy - objc-property-declaration
+
+objc-property-declaration
+=========================
+
+Finds property declarations in Objective-C files that do not follow the pattern
+of property names in Apple's programming guide. The property name should be
+in the format of Lower Camel Case.
+
+For code:
+
+.. code-block:: objc
+
+@property(nonatomic, assign) int LowerCamelCase;
+
+The fix will be:
+
+.. code-block:: objc
+
+@property(nonatomic, assign) int lowerCamelCase;
+
+The check will only fix 'CamelCase' to 'camelCase'. In some other cases we will
+only provide warning messages since the property name could be complicated.
+Users will need to come up with a proper name by their own.
+
+This check also accepts special acronyms as prefix. Such prefix will suppress
+the check of Lower Camel Case according to the guide:
+https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingBasics.html#//apple_ref/doc/uid/20001281-1002931-BBCFHEAB
+
+For a full list of well-known acronyms:
+https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CodingGuidelines/Articles/APIAbbreviations.html#//apple_ref/doc/uid/20001285-BCIHCGAE
+
+The corresponding style rule: https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingIvarsAndTypes.html#//apple_ref/doc/uid/20001284-1001757
+
+Options
+-------
+
+.. option:: Acronyms
+
+   Semicolon-separated list of acronys that can be used as prefix
+   of property names.
+
+   Defaults to ``ASCII;PDF;XML;HTML;URL;RTF;HTTP;TIFF;JPG;PNG;GIF;LZW;ROM;RGB;CMYK;MIDI;FTP``.
Index: docs/clang-tidy/checks/list.rst
===================================================================
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -173,15 +173,16 @@
    modernize-use-using
    mpi-buffer-deref
    mpi-type-mismatch
+   objc-forbidden-subclassing
+   objc-property-declaration
    performance-faster-string-find
    performance-for-range-copy
    performance-implicit-conversion-in-loop
    performance-inefficient-string-concatenation
    performance-inefficient-vector-operation
    performance-type-promotion-in-math-fn
    performance-unnecessary-copy-initialization
    performance-unnecessary-value-param
-   objc-forbidden-subclassing
    readability-avoid-const-params-in-decls
    readability-braces-around-statements
    readability-container-size-empty
Index: docs/clang-tidy/checks/google-objc-global-variable-declaration.rst
===================================================================
--- docs/clang-tidy/checks/google-objc-global-variable-declaration.rst
+++ docs/clang-tidy/checks/google-objc-global-variable-declaration.rst
@@ -3,7 +3,7 @@
 google-objc-global-variable-declaration
 =======================================
 
-Finds global variable declarations in Objective-C files that are not follow the pattern
+Finds global variable declarations in Objective-C files that do not follow the pattern
 of variable names in Google's Objective-C Style Guide.
 
 The corresponding style guide rule:
@@ -16,26 +16,31 @@
 For code:
 
 .. code-block:: objc
+
   static NSString* myString = @"hello";
 
 The fix will be:
 
 .. code-block:: objc
+
   static NSString* gMyString = @"hello";
 
 Another example of constant:
 
 .. code-block:: objc
+
   static NSString* const myConstString = @"hello";
 
 The fix will be:
 
 .. code-block:: objc
+
   static NSString* const kMyConstString = @"hello";
 
 However for code that prefixed with non-alphabetical characters like:
 
 .. code-block:: objc
+
   static NSString* __anotherString = @"world";
 
 The check will give a warning message but will not be able to suggest a fix. The user
Index: docs/ReleaseNotes.rst
===================================================================
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -57,6 +57,13 @@
 Improvements to clang-tidy
 --------------------------
 
+- New `objc-property-declaration
+  <http://clang.llvm.org/extra/clang-tidy/checks/objc-property-declaration.html>`_ check
+
+  Add new check for Objective-C code to ensure property
+  names follow the naming convention of Apple's programming
+  guide.
+
 - New `google-objc-global-variable-declaration
   <http://clang.llvm.org/extra/clang-tidy/checks/google-global-variable-declaration.html>`_ check
 
Index: clang-tidy/objc/PropertyDeclarationCheck.h
===================================================================
--- /dev/null
+++ clang-tidy/objc/PropertyDeclarationCheck.h
@@ -0,0 +1,44 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+
+#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>
+
+namespace clang {
+namespace tidy {
+namespace objc {
+
+/// Finds Objective-C property declarations which
+/// are not in Lower Camel Case.
+///
+/// The format of property should look like:
+/// @property(nonatomic) NSString *lowerCamelCase;
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/objc-property-declaration.html
+class PropertyDeclarationCheck : public ClangTidyCheck {
+public:
+  PropertyDeclarationCheck(StringRef Name, ClangTidyContext *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;
+};
+
+} // namespace objc
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_PROPERTY_DECLARATION_H
Index: clang-tidy/objc/PropertyDeclarationCheck.cpp
===================================================================
--- /dev/null
+++ clang-tidy/objc/PropertyDeclarationCheck.cpp
@@ -0,0 +1,105 @@
+//===--- 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "PropertyDeclarationCheck.h"
+#include "../utils/OptionsUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace objc {
+
+namespace {
+constexpr char DefaultSpecialAcronyms[] =
+    "ASCII;"
+    "PDF;"
+    "XML;"
+    "HTML;"
+    "URL;"
+    "RTF;"
+    "HTTP;"
+    "TIFF;"
+    "JPG;"
+    "PNG;"
+    "GIF;"
+    "LZW;"
+    "ROM;"
+    "RGB;"
+    "CMYK;"
+    "MIDI;"
+    "FTP";
+
+/// For now we will only fix 'CamelCase' property to
+/// 'camelCase'. For other cases the users need to
+/// come up with a proper name by their own.
+/// FIXME: provide fix for snake_case to snakeCase
+FixItHint generateFixItHint(const ObjCPropertyDecl *Decl) {
+  if (isupper(Decl->getName()[0])) {
+    auto NewName = Decl->getName().str();
+    NewName[0] = tolower(NewName[0]);
+    return FixItHint::CreateReplacement(
+        CharSourceRange::getTokenRange(SourceRange(Decl->getLocation())),
+        llvm::StringRef(NewName));
+  }
+  return FixItHint();
+}
+
+bool startsWithSpecialAcronyms(StringRef Name,
+                               const std::vector<std::string> &Prefixes) {
+  for (auto const &Prefix : Prefixes) {
+    if (Name.startswith(Prefix)) {
+      return true;
+    }
+  }
+  return false;
+}
+}  // namespace
+
+PropertyDeclarationCheck::PropertyDeclarationCheck(StringRef Name,
+                                                   ClangTidyContext *Context)
+    : ClangTidyCheck(Name, Context),
+      SpecialAcronyms(utils::options::parseStringList(
+          Options.get("Acronyms", DefaultSpecialAcronyms))) {}
+
+void PropertyDeclarationCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(
+      objcPropertyDecl(
+          // the property name should be in Lower Camel Case like
+          // 'lowerCamelCase'
+          unless(matchesName("::[a-z]+[a-z0-9]*([A-Z][a-z0-9]+)*$")))
+          .bind("property"),
+      this);
+}
+
+void PropertyDeclarationCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *MatchedDecl =
+      Result.Nodes.getNodeAs<ObjCPropertyDecl>("property");
+  assert(MatchedDecl->getName().size() > 0);
+  // Skip the check of lowerCamelCase if the name has prefix of special acronyms
+  if (startsWithSpecialAcronyms(MatchedDecl->getName(), SpecialAcronyms)) {
+    return;
+  }
+  diag(MatchedDecl->getLocation(),
+       "property '%0' is not in proper format according to property naming "
+       "convention. It should be in the format of lowerCamelCase or has "
+       "special acronyms")
+      << MatchedDecl->getName() << generateFixItHint(MatchedDecl);
+}
+
+void PropertyDeclarationCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
+  Options.store(Opts, "Acronyms",
+                utils::options::serializeStringList(SpecialAcronyms));
+}
+
+}  // namespace objc
+}  // namespace tidy
+}  // namespace clang
Index: clang-tidy/objc/ObjCTidyModule.cpp
===================================================================
--- clang-tidy/objc/ObjCTidyModule.cpp
+++ clang-tidy/objc/ObjCTidyModule.cpp
@@ -11,6 +11,7 @@
 #include "../ClangTidyModule.h"
 #include "../ClangTidyModuleRegistry.h"
 #include "ForbiddenSubclassingCheck.h"
+#include "PropertyDeclarationCheck.h"
 
 using namespace clang::ast_matchers;
 
@@ -23,6 +24,8 @@
   void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
     CheckFactories.registerCheck<ForbiddenSubclassingCheck>(
         "objc-forbidden-subclassing");
+    CheckFactories.registerCheck<PropertyDeclarationCheck>(
+        "objc-property-declaration");
   }
 };
 
Index: clang-tidy/objc/CMakeLists.txt
===================================================================
--- clang-tidy/objc/CMakeLists.txt
+++ clang-tidy/objc/CMakeLists.txt
@@ -3,6 +3,7 @@
 add_clang_library(clangTidyObjCModule
   ForbiddenSubclassingCheck.cpp
   ObjCTidyModule.cpp
+  PropertyDeclarationCheck.cpp
 
   LINK_LIBS
   clangAST
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to