stephanemoore created this revision.
stephanemoore added reviewers: benhamilton, Wizard.
Herald added subscribers: cfe-commits, jfb.

§1 Description

This changes the objc-property-declaration check to allow arbitrary acronyms 
and initialisms instead of using whitelisted acronyms. In Objective-C it is 
relatively common to use project prefixes in property names for the purposes of 
disambiguation. For example, the CIColor¹ and CGColor² properties on UIColor 
both represent symbol prefixes being used in proeprty names outside of Apple's 
accepted acronyms³. The union of Apple's accepted acronyms and all symbol 
prefixes that might be used for disambiguation in property declarations 
effectively allows for any arbitrary sequence of capital alphanumeric 
characters to be acceptable in property declarations. This change updates the 
check accordingly.

The test variants with custom configurations are deleted as part of this change 
because their configurations no longer impact behavior. The acronym 
configurations are currently preserved for backwards compatibility of check 
configuration.

[1] 
https://developer.apple.com/documentation/uikit/uicolor/1621951-cicolor?language=objc
[2] 
https://developer.apple.com/documentation/uikit/uicolor/1621954-cgcolor?language=objc
[3] 
https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CodingGuidelines/Articles/APIAbbreviations.html#//apple_ref/doc/uid/20001285-BCIHCGAE

§2 Test Notes

Changes verified by:
• Running clang-tidy unit tests.
• Used check_clang_tidy.py to verify expected output of processing 
objc-property-declaration.m


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D51832

Files:
  clang-tidy/objc/PropertyDeclarationCheck.cpp
  test/clang-tidy/objc-property-declaration-additional.m
  test/clang-tidy/objc-property-declaration-custom.m
  test/clang-tidy/objc-property-declaration.m

Index: test/clang-tidy/objc-property-declaration.m
===================================================================
--- test/clang-tidy/objc-property-declaration.m
+++ test/clang-tidy/objc-property-declaration.m
@@ -2,6 +2,9 @@
 @class NSData;
 @class NSString;
 @class UIViewController;
+@class CIColor;
+
+typedef void *CGColorRef;
 
 @interface Foo
 @property(assign, nonatomic) int NotCamelCase;
@@ -23,6 +26,9 @@
 @property(assign, nonatomic) int enableGLAcceleration;
 @property(assign, nonatomic) int ID;
 @property(assign, nonatomic) int hasADog;
+@property(nonatomic, readonly) CGColorRef CGColor;
+@property(nonatomic, readonly) CIColor *CIColor;
+@property(nonatomic, copy) NSArray<NSString *> *IDs;
 @end
 
 @interface Foo (Bar)
Index: test/clang-tidy/objc-property-declaration-custom.m
===================================================================
--- test/clang-tidy/objc-property-declaration-custom.m
+++ /dev/null
@@ -1,18 +0,0 @@
-// RUN: %check_clang_tidy %s objc-property-declaration %t \
-// RUN: -config='{CheckOptions: \
-// RUN:  [{key: objc-property-declaration.Acronyms, value: "ABC;TGIF"}, \
-// RUN:   {key: objc-property-declaration.IncludeDefaultAcronyms, value: 0}]}' \
-// RUN: --
-@class NSString;
-
-@interface Foo
-@property(assign, nonatomic) int AbcNotRealPrefix;
-// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: property name 'AbcNotRealPrefix' not using lowerCamelCase style or not prefixed in a category, according to the Apple Coding Guidelines [objc-property-declaration]
-// CHECK-FIXES: @property(assign, nonatomic) int abcNotRealPrefix;
-@property(assign, nonatomic) int ABCCustomPrefix;
-@property(strong, nonatomic) NSString *ABC_custom_prefix;
-// CHECK-MESSAGES: :[[@LINE-1]]:40: warning: property name 'ABC_custom_prefix' not using lowerCamelCase style or not prefixed in a category, according to the Apple Coding Guidelines [objc-property-declaration]
-@property(assign, nonatomic) int GIFIgnoreStandardAcronym;
-// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: property name 'GIFIgnoreStandardAcronym' not using lowerCamelCase style or not prefixed in a category, according to the Apple Coding Guidelines [objc-property-declaration]
-@property(strong, nonatomic) NSString *TGIF;
-@end
Index: test/clang-tidy/objc-property-declaration-additional.m
===================================================================
--- test/clang-tidy/objc-property-declaration-additional.m
+++ /dev/null
@@ -1,15 +0,0 @@
-// RUN: %check_clang_tidy %s objc-property-declaration %t \
-// RUN: -config='{CheckOptions: \
-// RUN:  [{key: objc-property-declaration.Acronyms, value: "ABC;TGIF"}]}' \
-// RUN: --
-@class NSString;
-
-@interface Foo
-@property(assign, nonatomic) int AbcNotRealPrefix;
-// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: property name 'AbcNotRealPrefix' not using lowerCamelCase style or not prefixed in a category, according to the Apple Coding Guidelines [objc-property-declaration]
-// CHECK-FIXES: @property(assign, nonatomic) int abcNotRealPrefix;
-@property(assign, nonatomic) int ABCCustomPrefix;
-@property(strong, nonatomic) NSString *ABC_custom_prefix;
-// CHECK-MESSAGES: :[[@LINE-1]]:40: warning: property name 'ABC_custom_prefix' not using lowerCamelCase style or not prefixed in a category, according to the Apple Coding Guidelines [objc-property-declaration]
-@property(assign, nonatomic) int GIFShouldIncludeStandardAcronym;
-@end
Index: clang-tidy/objc/PropertyDeclarationCheck.cpp
===================================================================
--- clang-tidy/objc/PropertyDeclarationCheck.cpp
+++ clang-tidy/objc/PropertyDeclarationCheck.cpp
@@ -34,91 +34,6 @@
   CategoryProperty = 2,
 };
 
-/// The acronyms are aggregated from multiple sources including
-/// https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CodingGuidelines/Articles/APIAbbreviations.html#//apple_ref/doc/uid/20001285-BCIHCGAE
-///
-/// Keep this list sorted.
-constexpr llvm::StringLiteral DefaultSpecialAcronyms[] = {
-    "[2-9]G",
-    "ACL",
-    "API",
-    "AR",
-    "ARGB",
-    "ASCII",
-    "AV",
-    "BGRA",
-    "CA",
-    "CF",
-    "CG",
-    "CI",
-    "CRC",
-    "CV",
-    "CMYK",
-    "DNS",
-    "FPS",
-    "FTP",
-    "GIF",
-    "GL",
-    "GPS",
-    "GUID",
-    "HD",
-    "HDR",
-    "HMAC",
-    "HTML",
-    "HTTP",
-    "HTTPS",
-    "HUD",
-    "ID",
-    "JPG",
-    "JS",
-    "LAN",
-    "LZW",
-    "MAC",
-    "MD",
-    "MDNS",
-    "MIDI",
-    "NS",
-    "OS",
-    "PDF",
-    "PIN",
-    "PNG",
-    "POI",
-    "PSTN",
-    "PTR",
-    "QA",
-    "QOS",
-    "RGB",
-    "RGBA",
-    "RGBX",
-    "RIPEMD",
-    "ROM",
-    "RPC",
-    "RTF",
-    "RTL",
-    "SC",
-    "SDK",
-    "SHA",
-    "SQL",
-    "SSO",
-    "TCP",
-    "TIFF",
-    "TTS",
-    "UI",
-    "URI",
-    "URL",
-    "UUID",
-    "VC",
-    "VOIP",
-    "VPN",
-    "VR",
-    "W",
-    "WAN",
-    "X",
-    "XML",
-    "Y",
-    "Z",
-};
-
 /// For now we will only fix 'CamelCase' or 'abc_CamelCase' property to
 /// 'camelCase' or 'abc_camelCase'. For other cases the users need to
 /// come up with a proper name by their own.
@@ -142,43 +57,39 @@
   return FixItHint();
 }
 
-std::string AcronymsGroupRegex(llvm::ArrayRef<std::string> EscapedAcronyms) {
-  return "(" +
-         llvm::join(EscapedAcronyms.begin(), EscapedAcronyms.end(), "s?|") +
-         "s?)";
-}
-
-std::string validPropertyNameRegex(llvm::ArrayRef<std::string> EscapedAcronyms,
-                                   bool UsedInMatcher) {
+std::string validPropertyNameRegex(bool UsedInMatcher) {
   // Allow any of these names:
   // foo
   // fooBar
   // url
   // urlString
+  // ID
+  // IDs
   // URL
   // URLString
   // bundleID
+  // CIColor
+  //
+  // Disallow names of this form:
+  // LongString
   std::string StartMatcher = UsedInMatcher ? "::" : "^";
-  std::string AcronymsMatcher = AcronymsGroupRegex(EscapedAcronyms);
-  return StartMatcher + "(" + AcronymsMatcher + "[A-Z]?)?[a-z]+[a-z0-9]*(" +
-         AcronymsMatcher + "|([A-Z][a-z0-9]+)|A|I)*$";
+  return StartMatcher + "([a-z]|[A-Z][A-Z0-9])[a-z0-9A-Z]*$";
 }
 
 bool hasCategoryPropertyPrefix(llvm::StringRef PropertyName) {
   auto RegexExp = llvm::Regex("^[a-zA-Z]+_[a-zA-Z0-9][a-zA-Z0-9_]+$");
   return RegexExp.match(PropertyName);
 }
 
-bool prefixedPropertyNameValid(llvm::StringRef PropertyName,
-                               llvm::ArrayRef<std::string> Acronyms) {
+bool prefixedPropertyNameValid(llvm::StringRef PropertyName) {
   size_t Start = PropertyName.find_first_of('_');
   assert(Start != llvm::StringRef::npos && Start + 1 < PropertyName.size());
   auto Prefix = PropertyName.substr(0, Start);
   if (Prefix.lower() != Prefix) {
     return false;
   }
   auto RegexExp =
-      llvm::Regex(llvm::StringRef(validPropertyNameRegex(Acronyms, false)));
+      llvm::Regex(llvm::StringRef(validPropertyNameRegex(false)));
   return RegexExp.match(PropertyName.substr(Start + 1));
 }
 }  // namespace
@@ -196,26 +107,12 @@
   if (!getLangOpts().ObjC1 && !getLangOpts().ObjC2) {
     return;
   }
-  if (IncludeDefaultAcronyms) {
-    EscapedAcronyms.reserve(llvm::array_lengthof(DefaultSpecialAcronyms) +
-                            SpecialAcronyms.size());
-    // No need to regex-escape the default acronyms.
-    EscapedAcronyms.insert(EscapedAcronyms.end(),
-                           std::begin(DefaultSpecialAcronyms),
-                           std::end(DefaultSpecialAcronyms));
-  } else {
-    EscapedAcronyms.reserve(SpecialAcronyms.size());
-  }
-  // In case someone defines a prefix which includes a regex
-  // special character, regex-escape all the user-defined prefixes.
-  std::transform(SpecialAcronyms.begin(), SpecialAcronyms.end(),
-                 std::back_inserter(EscapedAcronyms),
-                 [](const std::string &s) { return llvm::Regex::escape(s); });
+
   Finder->addMatcher(
       objcPropertyDecl(
           // the property name should be in Lower Camel Case like
           // 'lowerCamelCase'
-          unless(matchesName(validPropertyNameRegex(EscapedAcronyms, true))))
+          unless(matchesName(validPropertyNameRegex(true))))
           .bind("property"),
       this);
 }
@@ -227,14 +124,9 @@
   auto *DeclContext = MatchedDecl->getDeclContext();
   auto *CategoryDecl = llvm::dyn_cast<ObjCCategoryDecl>(DeclContext);
 
-  auto AcronymsRegex =
-      llvm::Regex("^" + AcronymsGroupRegex(EscapedAcronyms) + "$");
-  if (AcronymsRegex.match(MatchedDecl->getName())) {
-    return;
-  }
   if (CategoryDecl != nullptr &&
       hasCategoryPropertyPrefix(MatchedDecl->getName())) {
-    if (!prefixedPropertyNameValid(MatchedDecl->getName(), EscapedAcronyms) ||
+    if (!prefixedPropertyNameValid(MatchedDecl->getName()) ||
         CategoryDecl->IsClassExtension()) {
       NamingStyle Style = CategoryDecl->IsClassExtension() ? StandardProperty
                                                            : CategoryProperty;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to