]> granicus.if.org Git - clang/commitdiff
When producing code completion results for the Objective-C property
authorDouglas Gregor <dgregor@apple.com>
Mon, 18 Apr 2011 14:13:53 +0000 (14:13 +0000)
committerDouglas Gregor <dgregor@apple.com>
Mon, 18 Apr 2011 14:13:53 +0000 (14:13 +0000)
implementation

  @synthesize <property> =

also produce a completion for a to-be-synthesized ivar named
_<property>.

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

lib/Sema/SemaCodeComplete.cpp
test/Index/complete-properties.m

index ab1eb0587ac9f2a6acc2cfff0b77c5e1cabacb84..fa76db4c6387baad4b210cc74206e44103261cd1 100644 (file)
@@ -5372,14 +5372,51 @@ void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
 
   // Add all of the instance variables in this class and its superclasses.
   Results.EnterNewScope();
+  bool SawSimilarlyNamedIvar = false;
+  std::string NameWithPrefix;
+  NameWithPrefix += '_';
+  NameWithPrefix += PropertyName->getName().str();
+  std::string NameWithSuffix = PropertyName->getName().str();
+  NameWithSuffix += '_';
   for(; Class; Class = Class->getSuperClass()) {
     // FIXME: We could screen the type of each ivar for compatibility with
-    // the property, but is that being too paternal?
-    for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
-                                       IVarEnd = Class->ivar_end();
-         IVar != IVarEnd; ++IVar) 
-      Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
+    // the property, but is that being too paternal?    
+    for (ObjCIvarDecl *Ivar = Class->all_declared_ivar_begin(); Ivar; 
+         Ivar = Ivar->getNextIvar()) {
+      // Determine whether we've seen an ivar with a name similar to the 
+      // property.
+      if (!SawSimilarlyNamedIvar &&
+          (PropertyName->getName() == Ivar->getName() ||
+           NameWithPrefix == Ivar->getName() ||
+           NameWithSuffix == Ivar->getName()))
+        SawSimilarlyNamedIvar = true;
+      
+      Results.AddResult(Result(Ivar, 0), CurContext, 0, false);
+    }
+  }
+  
+  if (!SawSimilarlyNamedIvar) {
+    // Create ivar result _propName, that the user can use to synthesize
+    // an ivar of the appropriate type.
+    QualType T = Context.getObjCIdType();
+    
+    if (Class) {
+      if (ObjCPropertyDecl *Property
+                                = Class->FindPropertyDeclaration(PropertyName))
+        T = Property->getType().getNonReferenceType().getUnqualifiedType();
+    }
+    
+    unsigned Priority = CCP_MemberDeclaration;
+    typedef CodeCompletionResult Result;
+    CodeCompletionAllocator &Allocator = Results.getAllocator();
+    CodeCompletionBuilder Builder(Allocator, Priority,CXAvailability_Available);
+
+    Builder.AddResultTypeChunk(GetCompletionTypeString(T, Context, Allocator));
+    Builder.AddTypedTextChunk(Allocator.CopyString(NameWithPrefix));
+    Results.AddResult(Result(Builder.TakeString(), Priority, 
+                             CXCursor_ObjCIvarDecl));
   }
+  
   Results.ExitScope();
   
   HandleCodeCompleteResults(this, CodeCompleter, 
index 725f180f7c29f06957b05a84858c3e01078afd84..c513a91e95f5e9ab564b0783ebfec6dd01c12712 100644 (file)
@@ -41,8 +41,10 @@ id test(I3 *i3) {
 // CHECK-CC2-NEXT: ObjCPropertyDecl:{ResultType id}{TypedText Prop3}
 // CHECK-CC2: ObjCPropertyDecl:{ResultType id}{TypedText Prop4}
 // RUN: c-index-test -code-completion-at=%s:20:35 %s | FileCheck -check-prefix=CHECK-CC3 %s
-// CHECK-CC3: ObjCIvarDecl:{ResultType int}{TypedText RandomIVar}
-// CHECK-CC3: ObjCIvarDecl:{ResultType id}{TypedText StoredProp3}
+// CHECK-CC3: ObjCIvarDecl:{ResultType id}{TypedText _Prop3} (35)
+// CHECK-CC3: ObjCIvarDecl:{ResultType int}{TypedText RandomIVar} (35)
+// CHECK-CC3: ObjCIvarDecl:{ResultType id}{TypedText StoredProp3} (35)
+
 // RUN: c-index-test -code-completion-at=%s:21:10 %s | FileCheck -check-prefix=CHECK-CC4 %s
 // CHECK-CC4: ObjCPropertyDecl:{ResultType int}{TypedText Prop0}
 // CHECK-CC4-NEXT: ObjCPropertyDecl:{ResultType id}{TypedText Prop4}