]> granicus.if.org Git - clang/commitdiff
When code-completing inside an Objective-C method, give a slight
authorDouglas Gregor <dgregor@apple.com>
Fri, 27 Aug 2010 15:29:55 +0000 (15:29 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 27 Aug 2010 15:29:55 +0000 (15:29 +0000)
priority boost to methods with the same selector.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@112268 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Sema/CodeCompleteConsumer.h
lib/Sema/SemaCodeComplete.cpp
test/Index/complete-objc-message-id.m

index 46650baf2fabea9d1ee170a65cc5774e480edd04..28210576e0251740844946008f9b54939a789237 100644 (file)
@@ -69,7 +69,11 @@ enum {
   CCD_VoidMatch = -5,
   /// \brief The result is a C++ non-static member function whose qualifiers
   /// exactly match the object type on which the member function can be called.
-  CCD_ObjectQualifierMatch = -1
+  CCD_ObjectQualifierMatch = -1,
+  /// \brief The selector of the given message exactly matches the selector
+  /// of the current method, which might imply that some kind of delegation
+  /// is occurring.
+  CCD_SelectorMatch = -3
 };
 
 /// \brief Priority value factors by which we will divide or multiply the
index 8e1e6914c669479ff333e318e9928872fbf1cd02..384cf524c9eda4cc616e5cf05cfa90310c741cf5 100644 (file)
@@ -143,6 +143,9 @@ namespace {
     /// \brief Whether the \p ObjectTypeQualifiers field is active.
     bool HasObjectTypeQualifiers;
     
+    /// \brief The selector that we prefer.
+    Selector PreferredSelector;
+    
     void AdjustResultPriorityForPreferredType(Result &R);
 
   public:
@@ -187,6 +190,15 @@ namespace {
       HasObjectTypeQualifiers = true;
     }
     
+    /// \brief Set the preferred selector.
+    ///
+    /// When an Objective-C method declaration result is added, and that
+    /// method's selector matches this preferred selector, we give that method
+    /// a slight priority boost.
+    void setPreferredSelector(Selector Sel) {
+      PreferredSelector = Sel;
+    }
+    
     /// \brief Specify whether nested-name-specifiers are allowed.
     void allowNestedNameSpecifiers(bool Allow = true) {
       AllowNestedNameSpecifiers = Allow;
@@ -706,7 +718,14 @@ void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
   // Make sure that any given declaration only shows up in the result set once.
   if (!AllDeclsFound.insert(CanonDecl))
     return;
-  
+
+  // If this is an Objective-C method declaration whose selector matches our
+  // preferred selector, give it a priority boost.
+  if (!PreferredSelector.isNull())
+    if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(R.Declaration))
+      if (PreferredSelector == Method->getSelector())
+        R.Priority += CCD_SelectorMatch;
+
   // If the filter is for nested-name-specifiers, then this result starts a
   // nested-name-specifier.
   if (AsNestedNameSpecifier) {
@@ -714,7 +733,7 @@ void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
     R.Priority = CCP_NestedNameSpecifier;
   } else if (!PreferredType.isNull())
       AdjustResultPriorityForPreferredType(R);
-
+      
   // If this result is supposed to have an informative qualifier, add one.
   if (R.QualifierIsInformative && !R.Qualifier &&
       !R.StartsNestedNameSpecifier) {
@@ -787,6 +806,13 @@ void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
   if (InBaseClass)
     R.Priority += CCD_InBaseClass;
   
+  // If this is an Objective-C method declaration whose selector matches our
+  // preferred selector, give it a priority boost.
+  if (!PreferredSelector.isNull())
+    if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(R.Declaration))
+      if (PreferredSelector == Method->getSelector())
+        R.Priority += CCD_SelectorMatch;
+
   if (!PreferredType.isNull())
     AdjustResultPriorityForPreferredType(R);
   
@@ -3996,6 +4022,11 @@ void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
       Results.Ignore(SuperMethod);
   }
 
+  // If we're inside an Objective-C method definition, prefer its selector to
+  // others.
+  if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
+    Results.setPreferredSelector(CurMethod->getSelector());
+
   if (CDecl) 
     AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext, 
                    Results);  
@@ -4071,6 +4102,11 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
       Results.Ignore(SuperMethod);
   }
   
+  // If we're inside an Objective-C method definition, prefer its selector to
+  // others.
+  if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
+    Results.setPreferredSelector(CurMethod->getSelector());
+
   // If we're messaging an expression with type "id" or "Class", check
   // whether we know something special about the receiver that allows
   // us to assume a more-specific receiver type.
index a75ee4a81d5ca4bf73123d31236932dbc9055ef5..be42b9b855efdd1ff0066a180156a8c7284695df 100644 (file)
@@ -26,6 +26,11 @@ void message_id(B *b) {
   [[b superclass] B_method];
 }
 
+@implementation Unrelated
++ (id)alloc {
+  return [A alloc];
+}
+@end
 // RUN: c-index-test -code-completion-at=%s:24:14 %s | FileCheck -check-prefix=CHECK-CC1 %s
 // CHECK-CC1: ObjCInstanceMethodDecl:{ResultType id}{TypedText autorelease}
 // CHECK-CC1-NOT: B_method
@@ -40,3 +45,10 @@ void message_id(B *b) {
 // CHECK-CC3: ObjCInstanceMethodDecl:{ResultType id}{TypedText retain}
 
 
+// RUN: c-index-test -code-completion-at=%s:31:13 %s | FileCheck -check-prefix=CHECK-SELECTOR-PREF %s
+// CHECK-SELECTOR-PREF: ObjCClassMethodDecl:{ResultType id}{TypedText alloc} (17)
+// CHECK-SELECTOR-PREF: ObjCClassMethodDecl:{ResultType Class}{TypedText class} (20)
+// CHECK-SELECTOR-PREF: ObjCClassMethodDecl:{ResultType id}{TypedText init} (20)
+// CHECK-SELECTOR-PREF: ObjCClassMethodDecl:{ResultType id}{TypedText new} (20)
+// CHECK-SELECTOR-PREF: ObjCClassMethodDecl:{ResultType Class}{TypedText superclass} (20)
+