r183331 - Objective-C: Provide fixit with suggested spelling correction
Fariborz Jahanian
fjahanian at apple.com
Wed Jun 5 11:46:14 PDT 2013
Author: fjahanian
Date: Wed Jun 5 13:46:14 2013
New Revision: 183331
URL: http://llvm.org/viewvc/llvm-project?rev=183331&view=rev
Log:
Objective-C: Provide fixit with suggested spelling correction
for -Wundeclared-selector warnings. // rdar://14039037
Added:
cfe/trunk/test/FixIt/selector-fixit.m
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDeclObjC.cpp
cfe/trunk/lib/Sema/SemaExprObjC.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=183331&r1=183330&r2=183331&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Jun 5 13:46:14 2013
@@ -811,6 +811,9 @@ def error_dealloc_bad_result_type : Erro
"instead of %0">;
def warn_undeclared_selector : Warning<
"undeclared selector %0">, InGroup<UndeclaredSelector>, DefaultIgnore;
+def warn_undeclared_selector_with_typo : Warning<
+ "undeclared selector %0; did you mean %1?">,
+ InGroup<UndeclaredSelector>, DefaultIgnore;
def warn_implicit_atomic_property : Warning<
"property is assumed atomic by default">, InGroup<ImplicitAtomic>, DefaultIgnore;
def note_auto_readonly_iboutlet_fixup_suggest : Note<
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=183331&r1=183330&r2=183331&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Wed Jun 5 13:46:14 2013
@@ -2669,6 +2669,8 @@ public:
warn, /*instance*/false);
}
+ const ObjCMethodDecl *SelectorsForTypoCorrection(Selector Sel);
+
/// DiagnoseMismatchedMethodsInGlobalPool - This routine goes through list of
/// methods in global pool and issues diagnostic on identical selectors which
/// have mismathched types.
Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=183331&r1=183330&r2=183331&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Wed Jun 5 13:46:14 2013
@@ -2272,6 +2272,57 @@ ObjCMethodDecl *Sema::LookupImplementedM
}
static void
+HelperSelectorsForTypoCorrection(
+ SmallVectorImpl<const ObjCMethodDecl *> &BestMethod,
+ StringRef Typo, const ObjCMethodDecl * Method) {
+ const unsigned MaxEditDistance = 1;
+ unsigned BestEditDistance = MaxEditDistance + 1;
+ StringRef MethodName = Method->getSelector().getAsString();
+
+ unsigned MinPossibleEditDistance = abs((int)MethodName.size() - (int)Typo.size());
+ if (MinPossibleEditDistance > 0 &&
+ Typo.size() / MinPossibleEditDistance < 1)
+ return;
+ unsigned EditDistance = Typo.edit_distance(MethodName, true, MaxEditDistance);
+ if (EditDistance > MaxEditDistance)
+ return;
+ if (EditDistance == BestEditDistance)
+ BestMethod.push_back(Method);
+ else if (EditDistance < BestEditDistance) {
+ BestMethod.clear();
+ BestMethod.push_back(Method);
+ BestEditDistance = EditDistance;
+ }
+}
+
+const ObjCMethodDecl *
+Sema::SelectorsForTypoCorrection(Selector Sel) {
+ unsigned NumArgs = Sel.getNumArgs();
+ SmallVector<const ObjCMethodDecl *, 8> Methods;
+
+ 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))
+ 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))
+ Methods.push_back(M->Method);
+ }
+
+ SmallVector<const ObjCMethodDecl *, 8> SelectedMethods;
+ for (unsigned i = 0, e = Methods.size(); i < e; i++) {
+ HelperSelectorsForTypoCorrection(SelectedMethods,
+ Sel.getAsString(), Methods[i]);
+ }
+ return (SelectedMethods.size() == 1) ? SelectedMethods[0] : NULL;
+}
+
+static void
HelperToDiagnoseMismatchedMethodsInGlobalPool(Sema &S,
ObjCMethodList &MethList) {
ObjCMethodList *M = &MethList;
Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=183331&r1=183330&r2=183331&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Wed Jun 5 13:46:14 2013
@@ -968,8 +968,18 @@ ExprResult Sema::ParseObjCSelectorExpres
if (!Method)
Method = LookupFactoryMethodInGlobalPool(Sel,
SourceRange(LParenLoc, RParenLoc));
- if (!Method)
- Diag(SelLoc, diag::warn_undeclared_selector) << Sel;
+ if (!Method) {
+ if (const ObjCMethodDecl *OM = SelectorsForTypoCorrection(Sel)) {
+ Selector MatchedSel = OM->getSelector();
+ SourceRange SelectorRange(LParenLoc.getLocWithOffset(1),
+ RParenLoc.getLocWithOffset(-1));
+ Diag(SelLoc, diag::warn_undeclared_selector_with_typo)
+ << Sel << MatchedSel
+ << FixItHint::CreateReplacement(SelectorRange, MatchedSel.getAsString());
+
+ } else
+ Diag(SelLoc, diag::warn_undeclared_selector) << Sel;
+ }
if (!Method ||
Method->getImplementationControl() != ObjCMethodDecl::Optional) {
Added: cfe/trunk/test/FixIt/selector-fixit.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/selector-fixit.m?rev=183331&view=auto
==============================================================================
--- cfe/trunk/test/FixIt/selector-fixit.m (added)
+++ cfe/trunk/test/FixIt/selector-fixit.m Wed Jun 5 13:46:14 2013
@@ -0,0 +1,30 @@
+// RUN: cp %s %t
+// RUN: %clang_cc1 -x objective-c -Wundeclared-selector -fixit %t
+// RUN: %clang_cc1 -x objective-c -Wundeclared-selector -Werror %t
+// rdar://14039037
+
+ at interface NSObject @end
+
+ at interface LogoutController : NSObject
+- (void)close;
+- (void)closed;
+- (void) open : (id) file_id;
+ at end
+
+ at implementation LogoutController
+
+- (void)close { }
+- (void)closed { }
+
+- (SEL)Meth
+{
+ return @selector(cloze);
+}
+- (void) open : (id) file_id {}
+
+- (SEL)Meth1
+{
+ return @selector(ope:);
+}
+
+ at end
More information about the cfe-commits
mailing list