r184195 - Objective-C [qoi]: privide typo correction for selectors

Fariborz Jahanian fjahanian at apple.com
Tue Jun 18 08:31:36 PDT 2013


Author: fjahanian
Date: Tue Jun 18 10:31:36 2013
New Revision: 184195

URL: http://llvm.org/viewvc/llvm-project?rev=184195&view=rev
Log:
Objective-C [qoi]: privide typo correction for selectors
in addition of receiver having static type, but also when
receiver has dynamic type (of 'id' variety) as well as when
receiver is of 'Class' type vareity. // rdar://7853549

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp
    cfe/trunk/lib/Sema/SemaExprObjC.cpp
    cfe/trunk/test/FixIt/selector-fixit.m
    cfe/trunk/test/SemaObjC/arc.m
    cfe/trunk/test/SemaObjC/call-super-2.m
    cfe/trunk/test/SemaObjC/protocol-id-test-1.m
    cfe/trunk/test/SemaObjC/protocol-id-test-2.m

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=184195&r1=184194&r2=184195&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Jun 18 10:31:36 2013
@@ -4601,9 +4601,15 @@ def warn_instance_method_on_class_found
 def warn_inst_method_not_found : Warning<
   "instance method %objcinstance0 not found (return type defaults to 'id')">,
   InGroup<MethodAccess>;
-def warn_method_not_found_with_typo : Warning<
-  "%select{instance|class}0 method %1 not found (return type defaults to 'id')"
-  "; did you mean %2?">, InGroup<MethodAccess>;
+def warn_instance_method_not_found_with_typo : Warning<
+  "instance method %objcinstance0 not found (return type defaults to 'id')"
+  "; did you mean %objcinstance2?">, InGroup<MethodAccess>;
+def warn_class_method_not_found_with_typo : Warning<
+  "class method %objcclass0 not found (return type defaults to 'id')"
+  "; did you mean %objcclass2?">, InGroup<MethodAccess>;
+def error_method_not_found_with_typo : Error<
+  "%select{instance|class}1 method %0 not found "
+  "; did you mean %2?">;
 def error_no_super_class_message : Error<
   "no @interface declaration found in class messaging of %0">;
 def error_root_class_cannot_use_super : Error<

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=184195&r1=184194&r2=184195&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Tue Jun 18 10:31:36 2013
@@ -2309,21 +2309,45 @@ Sema::SelectorsForTypoCorrection(Selecto
                                  QualType ObjectType) {
   unsigned NumArgs = Sel.getNumArgs();
   SmallVector<const ObjCMethodDecl *, 8> Methods;
+  bool ObjectIsId = true, ObjectIsClass = true;
+  if (ObjectType.isNull())
+    ObjectIsId = ObjectIsClass = false;
+  else if (!ObjectType->isObjCObjectPointerType())
+    return 0;
+  else if (const ObjCObjectPointerType *ObjCPtr =
+           ObjectType->getAsObjCInterfacePointerType()) {
+    ObjectType = QualType(ObjCPtr->getInterfaceType(), 0);
+    ObjectIsId = ObjectIsClass = false;
+  }
+  else if (ObjectType->isObjCIdType() || ObjectType->isObjCQualifiedIdType())
+    ObjectIsClass = false;
+  else if (ObjectType->isObjCClassType() || ObjectType->isObjCQualifiedClassType())
+    ObjectIsId = false;
+  else
+    return 0;
   
   for (GlobalMethodPool::iterator b = MethodPool.begin(),
        e = MethodPool.end(); b != e; b++) {
     // instance methods
     for (ObjCMethodList *M = &b->second.first; M; M=M->getNext())
       if (M->Method &&
-          (M->Method->getSelector().getNumArgs() == NumArgs) &&
-          HelperIsMethodInObjCType(*this, M->Method->getSelector(), ObjectType))
-        Methods.push_back(M->Method);
+          (M->Method->getSelector().getNumArgs() == NumArgs)) {
+        if (ObjectIsId)
+          Methods.push_back(M->Method);
+        else if (!ObjectIsClass &&
+                 HelperIsMethodInObjCType(*this, M->Method->getSelector(), ObjectType))
+          Methods.push_back(M->Method);
+      }
     // class methods
     for (ObjCMethodList *M = &b->second.second; M; M=M->getNext())
       if (M->Method &&
-          (M->Method->getSelector().getNumArgs() == NumArgs) &&
-          HelperIsMethodInObjCType(*this, M->Method->getSelector(), ObjectType))
-        Methods.push_back(M->Method);
+          (M->Method->getSelector().getNumArgs() == NumArgs)) {
+        if (ObjectIsClass)
+          Methods.push_back(M->Method);
+        else if (!ObjectIsId &&
+                 HelperIsMethodInObjCType(*this, M->Method->getSelector(), ObjectType))
+          Methods.push_back(M->Method);
+      }
   }
   
   SmallVector<const ObjCMethodDecl *, 8> SelectedMethods;

Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=184195&r1=184194&r2=184195&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Tue Jun 18 10:31:36 2013
@@ -1232,17 +1232,17 @@ bool Sema::CheckMessageArgumentTypes(Qua
       DiagID = isClassMessage ? diag::warn_class_method_not_found
                               : diag::warn_inst_method_not_found;
     if (!getLangOpts().DebuggerSupport) {
-      const ObjCMethodDecl *OMD = 0;
-      if (const ObjCObjectPointerType *ObjCPtr =
-          ReceiverType->getAsObjCInterfacePointerType()) {
-        QualType ObjectType = QualType(ObjCPtr->getInterfaceType(), 0);
-        OMD = SelectorsForTypoCorrection(Sel, ObjectType);
-      }
-      if (OMD) {
+      const ObjCMethodDecl *OMD = SelectorsForTypoCorrection(Sel, ReceiverType);
+      if (OMD && !OMD->isInvalidDecl() && OMD->getSelector() != Sel) {
+        if (getLangOpts().ObjCAutoRefCount)
+          DiagID = diag::error_method_not_found_with_typo;
+        else
+          DiagID = isClassMessage ? diag::warn_class_method_not_found_with_typo
+                                  : diag::warn_instance_method_not_found_with_typo;
         Selector MatchedSel = OMD->getSelector();
         SourceRange SelectorRange(SelectorLocs.front(), SelectorLocs.back());
-        Diag(SelLoc, diag::warn_method_not_found_with_typo)
-          << isClassMessage << Sel << MatchedSel
+        Diag(SelLoc, DiagID)
+          << Sel<< isClassMessage << MatchedSel
           << FixItHint::CreateReplacement(SelectorRange, MatchedSel.getAsString());
       }
       else

Modified: cfe/trunk/test/FixIt/selector-fixit.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/selector-fixit.m?rev=184195&r1=184194&r2=184195&view=diff
==============================================================================
--- cfe/trunk/test/FixIt/selector-fixit.m (original)
+++ cfe/trunk/test/FixIt/selector-fixit.m Tue Jun 18 10:31:36 2013
@@ -37,4 +37,5 @@
 @implementation rdar7853549
 - (int) bounds { return 0; }
 - (void)PrivateMeth { int bounds = [self bonds]; }
+- (void)OtherPrivateMeth : (id) p { int bounds = [p bonds]; }
 @end

Modified: cfe/trunk/test/SemaObjC/arc.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/arc.m?rev=184195&r1=184194&r2=184195&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/arc.m (original)
+++ cfe/trunk/test/SemaObjC/arc.m Tue Jun 18 10:31:36 2013
@@ -411,7 +411,7 @@ void test17(void) {
 
 void test18(void) {
   id x;
-  [x test18]; // expected-error {{no known instance method for selector 'test18'}}
+  [x test18]; // expected-error {{instance method 'test18' not found ; did you mean 'test17'?}}
 }
 
 extern struct Test19 *test19a;

Modified: cfe/trunk/test/SemaObjC/call-super-2.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/call-super-2.m?rev=184195&r1=184194&r2=184195&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/call-super-2.m (original)
+++ cfe/trunk/test/SemaObjC/call-super-2.m Tue Jun 18 10:31:36 2013
@@ -35,7 +35,7 @@ id objc_getClass(const char *s);
 @implementation Derived
 + (int) class_func1
 {
-   int i = (size_t)[self class_func0];       // expected-warning {{class method '+class_func0' not found (return type defaults to 'id')}}
+   int i = (size_t)[self class_func0];       // expected-warning {{class method '+class_func0' not found (return type defaults to 'id'); did you mean '+class_func}}
    return i + (size_t)[super class_func0];   // expected-warning {{class method '+class_func0' not found (return type defaults to 'id')}}
 }
 + (int) class_func2
@@ -68,7 +68,7 @@ id objc_getClass(const char *s);
 }
 - (int) instance_func1
 {
-   int i = (size_t)[self instance_func0];     // expected-warning {{instance method 'instance_func0' not found (return type defaults to 'id'); did you mean}}
+   int i = (size_t)[self instance_func0];     // expected-warning {{instance method '-instance_func0' not found (return type defaults to 'id'); did you mean}}
    return i + (size_t)[super instance_func0]; // expected-warning {{'Object' may not respond to 'instance_func0'}}
 }
 - (int) instance_func2

Modified: cfe/trunk/test/SemaObjC/protocol-id-test-1.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/protocol-id-test-1.m?rev=184195&r1=184194&r2=184195&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/protocol-id-test-1.m (original)
+++ cfe/trunk/test/SemaObjC/protocol-id-test-1.m Tue Jun 18 10:31:36 2013
@@ -12,5 +12,5 @@
 @end
 
 @implementation INTF
-- (void)IMeth {INTF<P> *pi;  [pi Meth]; } // expected-warning {{instance method 'Meth' not found (return type defaults to 'id'); did you mean 'IMeth'?}}
+- (void)IMeth {INTF<P> *pi;  [pi Meth]; } // expected-warning {{instance method '-Meth' not found (return type defaults to 'id'); did you mean '-IMeth'?}}
 @end

Modified: cfe/trunk/test/SemaObjC/protocol-id-test-2.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/protocol-id-test-2.m?rev=184195&r1=184194&r2=184195&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/protocol-id-test-2.m (original)
+++ cfe/trunk/test/SemaObjC/protocol-id-test-2.m Tue Jun 18 10:31:36 2013
@@ -8,5 +8,5 @@
 @end
 
 @implementation INTF
-- (void)IMeth { [(id<P>)self Meth]; }  // expected-warning {{method '-Meth' not found (return type defaults to 'id')}}
+- (void)IMeth { [(id<P>)self Meth]; }  // expected-warning {{instance method '-Meth' not found (return type defaults to 'id'); did you mean '-IMeth'?}}
 @end





More information about the cfe-commits mailing list