[cfe-commits] r89277 - in /cfe/trunk: include/clang/Sema/CodeCompleteConsumer.h lib/Sema/CodeCompleteConsumer.cpp lib/Sema/SemaCodeComplete.cpp test/CodeCompletion/property.m test/Index/complete-property-flags.m

Douglas Gregor dgregor at apple.com
Wed Nov 18 16:01:58 PST 2009


Author: dgregor
Date: Wed Nov 18 18:01:57 2009
New Revision: 89277

URL: http://llvm.org/viewvc/llvm-project?rev=89277&view=rev
Log:
Improve code-completion results for the flags in an @property
declaration by providing patterns for "getter = <method>" and "setter
= <method>". As part of this, invented a new "pattern" result kind
that is merely a semantic string. The "pattern" result kind should
help with other kinds of code templates.

Added:
    cfe/trunk/test/Index/complete-property-flags.m
      - copied, changed from r89264, cfe/trunk/test/CodeCompletion/property.m
Removed:
    cfe/trunk/test/CodeCompletion/property.m
Modified:
    cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h
    cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp
    cfe/trunk/lib/Sema/SemaCodeComplete.cpp

Modified: cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h?rev=89277&r1=89276&r2=89277&view=diff

==============================================================================
--- cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h (original)
+++ cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h Wed Nov 18 18:01:57 2009
@@ -123,6 +123,9 @@
     /// \brief Create a new current-parameter chunk.
     static Chunk CreateCurrentParameter(llvm::StringRef CurrentParameter);
 
+    /// \brief Clone the given chunk.
+    Chunk Clone() const;
+    
     /// \brief Destroy this chunk, deallocating any memory it owns.
     void Destroy();
   };
@@ -192,15 +195,21 @@
   /// \brief Add a new chunk.
   void AddChunk(Chunk C) { Chunks.push_back(C); }
   
+  /// \brief Returns the text in the TypedText chunk.
+  const char *getTypedText() const;
+
   /// \brief Retrieve a string representation of the code completion string,
   /// which is mainly useful for debugging.
   std::string getAsString() const; 
   
+  /// \brief Clone this code-completion string.
+  CodeCompletionString *Clone() const;
+  
   /// \brief Serialize this code-completion string to the given stream.
   void Serialize(llvm::raw_ostream &OS) const;
   
   /// \brief Deserialize a code-completion string from the given string.
-  static CodeCompletionString *Deserialize(llvm::StringRef &Str);
+  static CodeCompletionString *Deserialize(llvm::StringRef &Str);  
 };
   
 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, 
@@ -220,7 +229,8 @@
     enum ResultKind {
       RK_Declaration = 0, //< Refers to a declaration
       RK_Keyword,         //< Refers to a keyword or symbol.
-      RK_Macro            //< Refers to a macro
+      RK_Macro,           //< Refers to a macro
+      RK_Pattern          //< Refers to a precomputed pattern.
     };
     
     /// \brief The kind of result stored here.
@@ -235,6 +245,10 @@
       /// or symbol's spelling.
       const char *Keyword;
       
+      /// \brief When Kind == RK_Pattern, the code-completion string that
+      /// describes the completion text to insert.
+      CodeCompletionString *Pattern;
+      
       /// \brief When Kind == RK_Macro, the identifier that refers to a macro.
       IdentifierInfo *Macro;
     };
@@ -277,6 +291,12 @@
      : Kind(RK_Macro), Macro(Macro), Rank(Rank), Hidden(false), 
        QualifierIsInformative(0), StartsNestedNameSpecifier(false),
        Qualifier(0) { }
+
+    /// \brief Build a result that refers to a pattern.
+    Result(CodeCompletionString *Pattern, unsigned Rank)
+      : Kind(RK_Pattern), Pattern(Pattern), Rank(Rank), Hidden(false), 
+        QualifierIsInformative(0), StartsNestedNameSpecifier(false),
+        Qualifier(0) { }
     
     /// \brief Retrieve the declaration stored in this result.
     NamedDecl *getDeclaration() const {
@@ -293,6 +313,8 @@
     /// \brief Create a new code-completion string that describes how to insert
     /// this result into a program.
     CodeCompletionString *CreateCodeCompletionString(Sema &S);
+    
+    void Destroy();
   };
     
   class OverloadCandidate {

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

==============================================================================
--- cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp (original)
+++ cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp Wed Nov 18 18:01:57 2009
@@ -117,6 +117,33 @@
   return Chunk(CK_CurrentParameter, CurrentParameter);
 }
 
+CodeCompletionString::Chunk CodeCompletionString::Chunk::Clone() const {
+  switch (Kind) {
+  case CK_TypedText:
+  case CK_Text:
+  case CK_Placeholder:
+  case CK_Informative:
+  case CK_CurrentParameter:
+  case CK_LeftParen:
+  case CK_RightParen:
+  case CK_LeftBracket:
+  case CK_RightBracket:
+  case CK_LeftBrace:
+  case CK_RightBrace:
+  case CK_LeftAngle:
+  case CK_RightAngle:
+  case CK_Comma:
+    return Chunk(Kind, Text);
+      
+  case CK_Optional: {
+    std::auto_ptr<CodeCompletionString> Opt(Optional->Clone());
+    return CreateOptional(Opt);
+  }
+  }
+
+  // Silence GCC warning.
+  return Chunk();
+}
 
 void
 CodeCompletionString::Chunk::Destroy() {
@@ -168,6 +195,20 @@
   return Result;
 }
 
+const char *CodeCompletionString::getTypedText() const {
+  for (iterator C = begin(), CEnd = end(); C != CEnd; ++C)
+    if (C->Kind == CK_TypedText)
+      return C->Text;
+  
+  return 0;
+}
+
+CodeCompletionString *CodeCompletionString::Clone() const {
+  CodeCompletionString *Result = new CodeCompletionString;
+  for (iterator C = begin(), CEnd = end(); C != CEnd; ++C)
+    Result->AddChunk(C->Clone());
+  return Result;
+}
 
 namespace {
   // Escape a string for XML-like formatting.
@@ -473,6 +514,13 @@
   return Result;
 }
 
+void CodeCompleteConsumer::Result::Destroy() {
+  if (Kind == RK_Pattern) {
+    delete Pattern;
+    Pattern = 0;
+  }
+}
+
 //===----------------------------------------------------------------------===//
 // Code completion overload candidate implementation
 //===----------------------------------------------------------------------===//
@@ -545,6 +593,12 @@
       OS << '\n';
       break;
     }
+        
+    case Result::RK_Pattern: {
+      OS << "Pattern : " << Results[I].Rank << " : " 
+         << Results[I].Pattern->getAsString() << '\n';
+      break;
+    }
     }
   }
   
@@ -627,6 +681,13 @@
         OS << '\n';
         break;
       }
+        
+      case Result::RK_Pattern: {
+        OS << "Pattern:";
+        Results[I].Pattern->Serialize(OS);
+        OS << '\n';
+        break;
+      }
     }
   }
   

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Wed Nov 18 18:01:57 2009
@@ -1066,6 +1066,17 @@
       else if (X.Rank > Y.Rank)
         return false;
       
+      // We use a special ordering for keywords and patterns, based on the
+      // typed text.
+      if ((X.Kind == Result::RK_Keyword || X.Kind == Result::RK_Pattern) &&
+          (Y.Kind == Result::RK_Keyword || Y.Kind == Result::RK_Pattern)) {
+        const char *XStr = (X.Kind == Result::RK_Keyword)? X.Keyword 
+                                                   : X.Pattern->getTypedText();
+        const char *YStr = (Y.Kind == Result::RK_Keyword)? Y.Keyword 
+                                                   : Y.Pattern->getTypedText();
+        return strcmp(XStr, YStr) < 0;
+      }
+      
       // Result kinds are ordered by decreasing importance.
       if (X.Kind < Y.Kind)
         return true;
@@ -1087,12 +1098,14 @@
           return isEarlierDeclarationName(X.Declaration->getDeclName(),
                                           Y.Declaration->getDeclName());
           
-        case Result::RK_Keyword:
-          return strcmp(X.Keyword, Y.Keyword) < 0;
-          
         case Result::RK_Macro:
           return llvm::LowercaseString(X.Macro->getName()) < 
                    llvm::LowercaseString(Y.Macro->getName());
+          
+        case Result::RK_Keyword:
+        case Result::RK_Pattern:
+          llvm::llvm_unreachable("Result kinds handled above");
+          break;
       }
       
       // Silence GCC warning.
@@ -1120,6 +1133,9 @@
 
   if (CodeCompleter)
     CodeCompleter->ProcessCodeCompleteResults(*S, Results, NumResults);
+  
+  for (unsigned I = 0; I != NumResults; ++I)
+    Results[I].Destroy();
 }
 
 void Sema::CodeCompleteOrdinaryName(Scope *S) {
@@ -1635,10 +1651,20 @@
     Results.MaybeAddResult(CodeCompleteConsumer::Result("copy", 0));
   if (!(Attributes & ObjCDeclSpec::DQ_PR_nonatomic))
     Results.MaybeAddResult(CodeCompleteConsumer::Result("nonatomic", 0));
-  if (!(Attributes & ObjCDeclSpec::DQ_PR_setter))
-    Results.MaybeAddResult(CodeCompleteConsumer::Result("setter", 0));
-  if (!(Attributes & ObjCDeclSpec::DQ_PR_getter))
-    Results.MaybeAddResult(CodeCompleteConsumer::Result("getter", 0));
+  if (!(Attributes & ObjCDeclSpec::DQ_PR_setter)) {
+    CodeCompletionString *Setter = new CodeCompletionString;
+    Setter->AddTypedTextChunk("setter");
+    Setter->AddTextChunk(" = ");
+    Setter->AddPlaceholderChunk("method");
+    Results.MaybeAddResult(CodeCompleteConsumer::Result(Setter, 0));
+  }
+  if (!(Attributes & ObjCDeclSpec::DQ_PR_getter)) {
+    CodeCompletionString *Getter = new CodeCompletionString;
+    Getter->AddTypedTextChunk("getter");
+    Getter->AddTextChunk(" = ");
+    Getter->AddPlaceholderChunk("method");
+    Results.MaybeAddResult(CodeCompleteConsumer::Result(Getter, 0));
+  }
   Results.ExitScope();
   HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
 }

Removed: cfe/trunk/test/CodeCompletion/property.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeCompletion/property.m?rev=89276&view=auto

==============================================================================
--- cfe/trunk/test/CodeCompletion/property.m (original)
+++ cfe/trunk/test/CodeCompletion/property.m (removed)
@@ -1,29 +0,0 @@
-// Note: the run lines follow their respective tests, since line/column
-// matter in this test.
-
- at interface Foo  {
-  void *isa;
-}
- at property(copy) Foo *myprop;
- at property(retain, nonatomic) id xx;
-// RUN: clang-cc -fsyntax-only -code-completion-at=%s:7:11 %s -o - | FileCheck -check-prefix=CC1 %s
-// CC1: assign
-// CC1-NEXT: copy
-// CC1-NEXT: getter
-// CC1-NEXT: nonatomic
-// CC1-NEXT: readonly
-// CC1-NEXT: readwrite
-// CC1-NEXT: retain
-// CC1-NEXT: setter
-// RUN: clang-cc -fsyntax-only -code-completion-at=%s:8:18 %s -o - | FileCheck -check-prefix=CC2 %s
-// CC2: assign
-// CC2-NEXT: copy
-// CC2-NEXT: getter
-// CC2-NEXT: nonatomic
-// CC2-NEXT: readonly
-// CC2-NEXT: readwrite
-// CC2-NEXT: setter
- at end
-
-
-

Copied: cfe/trunk/test/Index/complete-property-flags.m (from r89264, cfe/trunk/test/CodeCompletion/property.m)
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-property-flags.m?p2=cfe/trunk/test/Index/complete-property-flags.m&p1=cfe/trunk/test/CodeCompletion/property.m&r1=89264&r2=89277&rev=89277&view=diff

==============================================================================
--- cfe/trunk/test/CodeCompletion/property.m (original)
+++ cfe/trunk/test/Index/complete-property-flags.m Wed Nov 18 18:01:57 2009
@@ -6,23 +6,23 @@
 }
 @property(copy) Foo *myprop;
 @property(retain, nonatomic) id xx;
-// RUN: clang-cc -fsyntax-only -code-completion-at=%s:7:11 %s -o - | FileCheck -check-prefix=CC1 %s
-// CC1: assign
-// CC1-NEXT: copy
-// CC1-NEXT: getter
-// CC1-NEXT: nonatomic
-// CC1-NEXT: readonly
-// CC1-NEXT: readwrite
-// CC1-NEXT: retain
-// CC1-NEXT: setter
-// RUN: clang-cc -fsyntax-only -code-completion-at=%s:8:18 %s -o - | FileCheck -check-prefix=CC2 %s
-// CC2: assign
-// CC2-NEXT: copy
-// CC2-NEXT: getter
-// CC2-NEXT: nonatomic
-// CC2-NEXT: readonly
-// CC2-NEXT: readwrite
-// CC2-NEXT: setter
+// RUN: c-index-test -code-completion-at=%s:7:11 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: {TypedText assign}
+// CHECK-CC1-NEXT: {TypedText copy}
+// CHECK-CC1-NEXT: {TypedText getter}{Text  = }{Placeholder method}
+// CHECK-CC1-NEXT: {TypedText nonatomic}
+// CHECK-CC1-NEXT: {TypedText readonly}
+// CHECK-CC1-NEXT: {TypedText readwrite}
+// CHECK-CC1-NEXT: {TypedText retain}
+// CHECK-CC1-NEXT: {TypedText setter}{Text  = }{Placeholder method}
+// RUN: c-index-test -code-completion-at=%s:8:18 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: {TypedText assign}
+// CHECK-CC2-NEXT: {TypedText copy}
+// CHECK-CC2-NEXT: {TypedText getter}{Text  = }{Placeholder method}
+// CHECK-CC2-NEXT: {TypedText nonatomic}
+// CHECK-CC2-NEXT: {TypedText readonly}
+// CHECK-CC2-NEXT: {TypedText readwrite}
+// CHECK-CC2-NEXT: {TypedText setter}{Text  = }{Placeholder method}
 @end
 
 





More information about the cfe-commits mailing list