[cfe-commits] r112186 - in /cfe/trunk: include/clang/Sema/Action.h include/clang/Sema/CodeCompleteConsumer.h include/clang/Sema/Sema.h lib/Frontend/ASTUnit.cpp lib/Parse/ParseObjc.cpp lib/Sema/SemaCodeComplete.cpp test/Index/complete-at-exprstmt.m tools/libclang/CIndexCodeCompletion.cpp

Douglas Gregor dgregor at apple.com
Thu Aug 26 08:07:07 PDT 2010


Author: dgregor
Date: Thu Aug 26 10:07:07 2010
New Revision: 112186

URL: http://llvm.org/viewvc/llvm-project?rev=112186&view=rev
Log:
Implement code completion for @selector expressions

Modified:
    cfe/trunk/include/clang/Sema/Action.h
    cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Frontend/ASTUnit.cpp
    cfe/trunk/lib/Parse/ParseObjc.cpp
    cfe/trunk/lib/Sema/SemaCodeComplete.cpp
    cfe/trunk/test/Index/complete-at-exprstmt.m
    cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp

Modified: cfe/trunk/include/clang/Sema/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Action.h?rev=112186&r1=112185&r2=112186&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Action.h (original)
+++ cfe/trunk/include/clang/Sema/Action.h Thu Aug 26 10:07:07 2010
@@ -3078,6 +3078,16 @@
   virtual void CodeCompleteObjCForCollection(Scope *S, 
                                              DeclGroupPtrTy IterationVar) { }
   
+  /// \brief Code completion for an Objective-C @selector expression, in which
+  /// we may have already parsed parts of the selector.
+  ///
+  /// \param S The scope in which the @selector expression occurs.
+  /// \param SelIdents The identifiers that describe the selector (thus far).
+  /// \param NumSelIdents The number of identifiers in \p SelIdents.
+  virtual void CodeCompleteObjCSelector(Scope *S,
+                                        IdentifierInfo **SelIdents,
+                                        unsigned NumSelIdents) { }
+  
   /// \brief Code completion for a list of protocol references in Objective-C,
   /// such as P1 and P2 in \c id<P1,P2>.
   ///

Modified: cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h?rev=112186&r1=112185&r2=112186&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h (original)
+++ cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h Thu Aug 26 10:07:07 2010
@@ -190,7 +190,9 @@
     ///
     /// This context usually implies that no completions should be added,
     /// unless they come from an appropriate natural-language dictionary.
-    CCC_NaturalLanguage
+    CCC_NaturalLanguage,
+    /// \brief Code completion for a selector, as in an @selector expression.
+    CCC_SelectorName
   };
 
 private:

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=112186&r1=112185&r2=112186&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Aug 26 10:07:07 2010
@@ -4202,6 +4202,9 @@
                                                unsigned NumSelIdents);
   virtual void CodeCompleteObjCForCollection(Scope *S, 
                                              DeclGroupPtrTy IterationVar);
+  virtual void CodeCompleteObjCSelector(Scope *S,
+                                        IdentifierInfo **SelIdents,
+                                        unsigned NumSelIdents);
   virtual void CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
                                                   unsigned NumProtocols);
   virtual void CodeCompleteObjCProtocolDecl(Scope *S);

Modified: cfe/trunk/lib/Frontend/ASTUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTUnit.cpp?rev=112186&r1=112185&r2=112186&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/ASTUnit.cpp (original)
+++ cfe/trunk/lib/Frontend/ASTUnit.cpp Thu Aug 26 10:07:07 2010
@@ -1554,6 +1554,7 @@
   case CodeCompletionContext::CCC_PreprocessorExpression:
   case CodeCompletionContext::CCC_PreprocessorDirective:
   case CodeCompletionContext::CCC_NaturalLanguage:
+  case CodeCompletionContext::CCC_SelectorName:
     // We're looking for nothing, or we're looking for names that cannot
     // be hidden.
     return;

Modified: cfe/trunk/lib/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseObjc.cpp?rev=112186&r1=112185&r2=112186&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/lib/Parse/ParseObjc.cpp Thu Aug 26 10:07:07 2010
@@ -2194,6 +2194,15 @@
   llvm::SmallVector<IdentifierInfo *, 12> KeyIdents;
   SourceLocation LParenLoc = ConsumeParen();
   SourceLocation sLoc;
+  
+  if (Tok.is(tok::code_completion)) {
+    Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents.data(),
+                                     KeyIdents.size());
+    ConsumeCodeCompletionToken();
+    MatchRHSPunctuation(tok::r_paren, LParenLoc);
+    return ExprError();
+  }
+  
   IdentifierInfo *SelIdent = ParseObjCSelectorPiece(sLoc);
   if (!SelIdent && Tok.isNot(tok::colon)) // missing selector name.
     return ExprError(Diag(Tok, diag::err_expected_ident));
@@ -2209,6 +2218,15 @@
       ConsumeToken(); // Eat the ':'.
       if (Tok.is(tok::r_paren))
         break;
+      
+      if (Tok.is(tok::code_completion)) {
+        Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents.data(),
+                                         KeyIdents.size());
+        ConsumeCodeCompletionToken();
+        MatchRHSPunctuation(tok::r_paren, LParenLoc);
+        return ExprError();
+      }
+
       // Check for another keyword selector.
       SourceLocation Loc;
       SelIdent = ParseObjCSelectorPiece(Loc);

Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=112186&r1=112185&r2=112186&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Thu Aug 26 10:07:07 2010
@@ -25,6 +25,7 @@
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/Twine.h"
 #include <list>
 #include <map>
 #include <vector>
@@ -3401,26 +3402,33 @@
   MK_OneArgSelector //< One-argument selector.
 };
 
-static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
-                                   ObjCMethodKind WantKind,
-                                   IdentifierInfo **SelIdents,
-                                   unsigned NumSelIdents) {
-  Selector Sel = Method->getSelector();
+static bool isAcceptableObjCSelector(Selector Sel,
+                                     ObjCMethodKind WantKind,
+                                     IdentifierInfo **SelIdents,
+                                     unsigned NumSelIdents) {
   if (NumSelIdents > Sel.getNumArgs())
     return false;
-      
+  
   switch (WantKind) {
-  case MK_Any:             break;
-  case MK_ZeroArgSelector: return Sel.isUnarySelector();
-  case MK_OneArgSelector:  return Sel.getNumArgs() == 1;
+    case MK_Any:             break;
+    case MK_ZeroArgSelector: return Sel.isUnarySelector();
+    case MK_OneArgSelector:  return Sel.getNumArgs() == 1;
   }
-
+  
   for (unsigned I = 0; I != NumSelIdents; ++I)
     if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
       return false;
-
+  
   return true;
 }
+
+static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
+                                   ObjCMethodKind WantKind,
+                                   IdentifierInfo **SelIdents,
+                                   unsigned NumSelIdents) {
+  return isAcceptableObjCSelector(Method->getSelector(), WantKind, SelIdents,
+                                  NumSelIdents);
+}
                                    
 /// \brief Add all of the Objective-C methods in the given Objective-C 
 /// container to the set of results.
@@ -3979,6 +3987,57 @@
   CodeCompleteExpression(S, Data);
 }
 
+void Sema::CodeCompleteObjCSelector(Scope *S, IdentifierInfo **SelIdents,
+                                    unsigned NumSelIdents) {
+  // If we have an external source, load the entire class method
+  // pool from the AST file.
+  if (ExternalSource) {
+    for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
+         I != N; ++I) {
+      Selector Sel = ExternalSource->GetExternalSelector(I);
+      if (Sel.isNull() || MethodPool.count(Sel))
+        continue;
+      
+      ReadMethodPool(Sel);
+    }
+  }
+  
+  ResultBuilder Results(*this);
+  Results.EnterNewScope();
+  for (GlobalMethodPool::iterator M = MethodPool.begin(),
+                               MEnd = MethodPool.end();
+       M != MEnd; ++M) {
+    
+    Selector Sel = M->first;
+    if (!isAcceptableObjCSelector(Sel, MK_Any, SelIdents, NumSelIdents))
+      continue;
+
+    CodeCompletionString *Pattern = new CodeCompletionString;
+    if (Sel.isUnarySelector()) {
+      Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
+      Results.AddResult(Pattern);
+      continue;
+    }
+    
+    for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I) {
+      std::string Piece = Sel.getIdentifierInfoForSlot(I)->getName().str();
+      Piece += ':';
+      if (I < NumSelIdents)
+        Pattern->AddInformativeChunk(Piece);
+      else if (I == NumSelIdents)
+        Pattern->AddTypedTextChunk(Piece);
+      else
+        Pattern->AddTextChunk(Piece);
+    }
+    Results.AddResult(Pattern);
+  }
+  Results.ExitScope();
+  
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_SelectorName,
+                            Results.data(), Results.size());
+}
+
 /// \brief Add all of the protocol declarations that we find in the given
 /// (translation unit) context.
 static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,

Modified: cfe/trunk/test/Index/complete-at-exprstmt.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-at-exprstmt.m?rev=112186&r1=112185&r2=112186&view=diff
==============================================================================
--- cfe/trunk/test/Index/complete-at-exprstmt.m (original)
+++ cfe/trunk/test/Index/complete-at-exprstmt.m Thu Aug 26 10:07:07 2010
@@ -9,6 +9,16 @@
   @synchronized (@encode(MyClass)) { }
 }
 @end
+
+ at interface A
++ (int)add:(int)x to:(int)y;
++ (int)add:(int)x to:(int)y plus:(int)z;
+ at end
+
+void f() {
+  @selector(add:to:);
+}
+
 // RUN: c-index-test -code-completion-at=%s:9:4 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC1 %s
 // CHECK-CC1: {TypedText encode}{LeftParen (}{Placeholder type-name}{RightParen )}
 // CHECK-CC1: {TypedText protocol}{LeftParen (}{Placeholder protocol-name}{RightParen )}
@@ -35,3 +45,11 @@
 // CHECK-CC3: ObjCInterfaceDecl:{TypedText MyClass}
 // CHECK-CC3: TypedefDecl:{TypedText SEL}
 // CHECK-CC3: NotImplemented:{ResultType MyClass *}{TypedText self}
+// RUN: c-index-test -code-completion-at=%s:19:13 %s | FileCheck -check-prefix=CHECK-CC4 %s
+// CHECK-CC4: NotImplemented:{TypedText add:}{Text to:} (30)
+// CHECK-CC4: NotImplemented:{TypedText add:}{Text to:}{Text plus:} (30)
+// CHECK-CC4: NotImplemented:{TypedText myMethod:} (30)
+// RUN: c-index-test -code-completion-at=%s:19:17 %s | FileCheck -check-prefix=CHECK-CC5 %s
+// CHECK-CC5: NotImplemented:{Informative add:}{TypedText to:} (30)
+// CHECK-CC5: NotImplemented:{Informative add:}{TypedText to:}{Text plus:} (30)
+

Modified: cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp?rev=112186&r1=112185&r2=112186&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp (original)
+++ cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp Thu Aug 26 10:07:07 2010
@@ -818,4 +818,4 @@
                                        unsigned NumResults) {
     std::stable_sort(Results, Results + NumResults, OrderCompletionResults());
   }
-}
\ No newline at end of file
+}





More information about the cfe-commits mailing list