[cfe-commits] r89207 - in /cfe/trunk: include/clang/Parse/Action.h lib/Parse/ParseObjc.cpp lib/Sema/Sema.h lib/Sema/SemaCodeComplete.cpp test/Index/complete-interfaces.m

Douglas Gregor dgregor at apple.com
Wed Nov 18 08:26:40 PST 2009


Author: dgregor
Date: Wed Nov 18 10:26:39 2009
New Revision: 89207

URL: http://llvm.org/viewvc/llvm-project?rev=89207&view=rev
Log:
Code completion for Objective-C class names after @interface,
@implementation, and in the declaration of the superclass of an
@interface.

Added:
    cfe/trunk/test/Index/complete-interfaces.m
Modified:
    cfe/trunk/include/clang/Parse/Action.h
    cfe/trunk/lib/Parse/ParseObjc.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaCodeComplete.cpp

Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=89207&r1=89206&r2=89207&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Wed Nov 18 10:26:39 2009
@@ -2371,6 +2371,24 @@
   ///
   /// \param S the scope in which the protocol declaration occurs.
   virtual void CodeCompleteObjCProtocolDecl(Scope *S) { }
+
+  /// \brief Code completion for an Objective-C interface, after the
+  /// @interface but before any identifier.
+  virtual void CodeCompleteObjCInterfaceDecl(Scope *S) { }
+
+  /// \brief Code completion for the superclass of an Objective-C
+  /// interface, after the ':'.
+  ///
+  /// \param S the scope in which the interface declaration occurs.
+  ///
+  /// \param ClassName the name of the class being defined.
+  virtual void CodeCompleteObjCSuperclass(Scope *S, 
+                                          IdentifierInfo *ClassName) {
+  }
+
+  /// \brief Code completion for an Objective-C implementation, after the
+  /// @implementation but before any identifier.
+  virtual void CodeCompleteObjCImplementationDecl(Scope *S) { }
   //@}
 };
 

Modified: cfe/trunk/lib/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseObjc.cpp?rev=89207&r1=89206&r2=89207&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/lib/Parse/ParseObjc.cpp Wed Nov 18 10:26:39 2009
@@ -123,6 +123,12 @@
          "ParseObjCAtInterfaceDeclaration(): Expected @interface");
   ConsumeToken(); // the "interface" identifier
 
+  // Code completion after '@interface'.
+  if (Tok.is(tok::code_completion)) {
+    Actions.CodeCompleteObjCInterfaceDecl(CurScope);
+    ConsumeToken();
+  }
+
   if (Tok.isNot(tok::identifier)) {
     Diag(Tok, diag::err_expected_ident); // missing class or category name.
     return DeclPtrTy();
@@ -181,6 +187,13 @@
 
   if (Tok.is(tok::colon)) { // a super class is specified.
     ConsumeToken();
+
+    // Code completion of superclass names.
+    if (Tok.is(tok::code_completion)) {
+      Actions.CodeCompleteObjCSuperclass(CurScope, nameId);
+      ConsumeToken();
+    }
+
     if (Tok.isNot(tok::identifier)) {
       Diag(Tok, diag::err_expected_ident); // missing super class name.
       return DeclPtrTy();
@@ -1078,6 +1091,12 @@
          "ParseObjCAtImplementationDeclaration(): Expected @implementation");
   ConsumeToken(); // the "implementation" identifier
 
+  // Code completion after '@implementation'.
+  if (Tok.is(tok::code_completion)) {
+    Actions.CodeCompleteObjCImplementationDecl(CurScope);
+    ConsumeToken();
+  }
+
   if (Tok.isNot(tok::identifier)) {
     Diag(Tok, diag::err_expected_ident); // missing class or category name.
     return DeclPtrTy();

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=89207&r1=89206&r2=89207&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Wed Nov 18 10:26:39 2009
@@ -3645,7 +3645,11 @@
   virtual void CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
                                                   unsigned NumProtocols);
   virtual void CodeCompleteObjCProtocolDecl(Scope *S);
- //@}
+  virtual void CodeCompleteObjCInterfaceDecl(Scope *S);
+  virtual void CodeCompleteObjCSuperclass(Scope *S, 
+                                          IdentifierInfo *ClassName);
+  virtual void CodeCompleteObjCImplementationDecl(Scope *S);
+  //@}
   
   //===--------------------------------------------------------------------===//
   // Extra semantic analysis beyond the C type system

Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=89207&r1=89206&r2=89207&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Wed Nov 18 10:26:39 2009
@@ -1885,3 +1885,73 @@
   Results.ExitScope();
   HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
 }
+
+/// \brief Add all of the Objective-C interface declarations that we find in
+/// the given (translation unit) context.
+static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
+                                bool OnlyForwardDeclarations,
+                                bool OnlyUnimplemented,
+                                ResultBuilder &Results) {
+  typedef CodeCompleteConsumer::Result Result;
+  
+  for (DeclContext::decl_iterator D = Ctx->decls_begin(), 
+                               DEnd = Ctx->decls_end();
+       D != DEnd; ++D) {
+    // Record any interfaces we find.
+    if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
+      if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
+          (!OnlyUnimplemented || !Class->getImplementation()))
+        Results.MaybeAddResult(Result(Class, 0), CurContext);
+
+    // Record any forward-declared interfaces we find.
+    if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
+      for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
+           C != CEnd; ++C)
+        if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
+            (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
+          Results.MaybeAddResult(Result(C->getInterface(), 0), CurContext);
+    }
+  }
+}
+
+void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) { 
+  ResultBuilder Results(*this);
+  Results.EnterNewScope();
+  
+  // Add all classes.
+  AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
+                      false, Results);
+
+  Results.ExitScope();
+  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName) { 
+  ResultBuilder Results(*this);
+  Results.EnterNewScope();
+  
+  // Make sure that we ignore the class we're currently defining.
+  NamedDecl *CurClass
+    = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
+  if (isa<ObjCInterfaceDecl>(CurClass))
+    Results.Ignore(CurClass);
+
+  // Add all classes.
+  AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
+                      false, Results);
+
+  Results.ExitScope();
+  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteObjCImplementationDecl(Scope *S) { 
+  ResultBuilder Results(*this);
+  Results.EnterNewScope();
+
+  // Add all unimplemented classes.
+  AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
+                      true, Results);
+
+  Results.ExitScope();
+  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}

Added: cfe/trunk/test/Index/complete-interfaces.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-interfaces.m?rev=89207&view=auto

==============================================================================
--- cfe/trunk/test/Index/complete-interfaces.m (added)
+++ cfe/trunk/test/Index/complete-interfaces.m Wed Nov 18 10:26:39 2009
@@ -0,0 +1,43 @@
+/* Note: the RUN lines are near the end of the file, since line/column
+   matter for this test. */
+
+ at class Int1, Int2, Int3, Int4;
+
+ at interface Int3 
+{
+}
+ at end
+
+ at interface Int2 : Int3
+{
+}
+ at end
+
+ at implementation Int2
+ at end
+
+ at implementation Int3
+ at end
+
+// RUN: c-index-test -code-completion-at=%s:6:12 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: ObjCInterfaceDecl:{TypedText Int1}
+// CHECK-CC1: ObjCInterfaceDecl:{TypedText Int2}
+// CHECK-CC1: ObjCInterfaceDecl:{TypedText Int3}
+// CHECK-CC1: ObjCInterfaceDecl:{TypedText Int4}
+// RUN: c-index-test -code-completion-at=%s:11:12 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: ObjCInterfaceDecl:{TypedText Int1}
+// CHECK-CC2-NEXT: ObjCInterfaceDecl:{TypedText Int2}
+// CHECK-CC2-NEXT: ObjCInterfaceDecl:{TypedText Int4}
+// RUN: c-index-test -code-completion-at=%s:11:19 %s | FileCheck -check-prefix=CHECK-CC3 %s
+// CHECK-CC3: ObjCInterfaceDecl:{TypedText Int1}
+// CHECK-CC3-NEXT: ObjCInterfaceDecl:{TypedText Int3}
+// CHECK-CC3-NEXT: ObjCInterfaceDecl:{TypedText Int4}
+// RUN: c-index-test -code-completion-at=%s:16:17 %s | FileCheck -check-prefix=CHECK-CC4 %s
+// CHECK-CC4: ObjCInterfaceDecl:{TypedText Int1}
+// CHECK-CC4-NEXT: ObjCInterfaceDecl:{TypedText Int2}
+// CHECK-CC4-NEXT: ObjCInterfaceDecl:{TypedText Int3}
+// CHECK-CC4-NEXT: ObjCInterfaceDecl:{TypedText Int4}
+// RUN: c-index-test -code-completion-at=%s:19:17 %s | FileCheck -check-prefix=CHECK-CC5 %s
+// CHECK-CC5: ObjCInterfaceDecl:{TypedText Int1}
+// CHECK-CC5-NEXT: ObjCInterfaceDecl:{TypedText Int3}
+// CHECK-CC5-NEXT: ObjCInterfaceDecl:{TypedText Int4}





More information about the cfe-commits mailing list