CrisCristescu updated this revision to Diff 65401.
CrisCristescu marked 3 inline comments as done.
CrisCristescu added a comment.

Addressing some sugesstions.


Repository:
  rL LLVM

https://reviews.llvm.org/D17820

Files:
  include/clang/Lex/Preprocessor.h
  include/clang/Sema/CodeCompleteConsumer.h
  lib/Lex/Lexer.cpp
  lib/Lex/Preprocessor.cpp
  lib/Sema/CodeCompleteConsumer.cpp
  test/CodeCompletion/filter-function-name.cpp
  test/CodeCompletion/filter-member-access.cpp
  test/CodeCompletion/filter-namespace.cpp
  test/CodeCompletion/filter-ordinary-name.cpp
  test/CodeCompletion/objc-message.mm
  test/Index/complete-method-decls.m
  test/Index/complete-objc-message-id.m
  test/Index/complete-objc-message.m
  test/Index/complete-recovery.m
  test/Index/complete-super.m

Index: test/Index/complete-super.m
===================================================================
--- test/Index/complete-super.m
+++ test/Index/complete-super.m
@@ -60,16 +60,16 @@
 // RUN: c-index-test -code-completion-at=%s:20:16 %s | FileCheck -check-prefix=CHECK-ADD-TO %s
 // CHECK-ADD-TO: ObjCInstanceMethodDecl:{ResultType void}{Informative add:}{TypedText to:}{Placeholder b} (20)
 
-// RUN: c-index-test -code-completion-at=%s:24:28 %s | FileCheck -check-prefix=CHECK-SELECTOR-FIRST %s
+// RUN: c-index-test -code-completion-at=%s:24:29 %s | FileCheck -check-prefix=CHECK-SELECTOR-FIRST %s
 // CHECK-SELECTOR-FIRST: ObjCClassMethodDecl:{ResultType void}{Informative select:}{TypedText first:}{Placeholder a}{HorizontalSpace  }{Text second:}{Placeholder b} (20)
 
 // Check "super" completion at the third identifier
 // RUN: c-index-test -code-completion-at=%s:24:37 %s | FileCheck -check-prefix=CHECK-SELECTOR-SECOND %s
 // CHECK-SELECTOR-SECOND: ObjCClassMethodDecl:{ResultType void}{Informative select:}{Informative first:}{TypedText second:}{Placeholder b} (20)
 
 // Check "super" completion with missing '['.
 // RUN: c-index-test -code-completion-at=%s:25:10 %s | FileCheck -check-prefix=CHECK-SELECTOR-SELECTOR %s
-// RUN: c-index-test -code-completion-at=%s:25:28 %s | FileCheck -check-prefix=CHECK-SELECTOR-FIRST %s
+// RUN: c-index-test -code-completion-at=%s:25:29 %s | FileCheck -check-prefix=CHECK-SELECTOR-FIRST %s
 // RUN: c-index-test -code-completion-at=%s:25:37 %s | FileCheck -check-prefix=CHECK-SELECTOR-SECOND %s
 
 // Check "super" completion for a method declared in a category.
Index: test/Index/complete-recovery.m
===================================================================
--- test/Index/complete-recovery.m
+++ test/Index/complete-recovery.m
@@ -26,7 +26,7 @@
 // Test case for fix committed in r145441.
 // RUN: env CINDEXTEST_CODE_COMPLETE_PATTERNS=1 c-index-test -code-completion-at=%s:9:20 %s -fms-compatibility | FileCheck -check-prefix=CHECK-CC1 %s
 
-// RUN: env CINDEXTEST_CODE_COMPLETE_PATTERNS=1 c-index-test -code-completion-at=%s:10:24 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// RUN: env CINDEXTEST_CODE_COMPLETE_PATTERNS=1 c-index-test -code-completion-at=%s:10:25 %s | FileCheck -check-prefix=CHECK-CC2 %s
 // CHECK-CC2: NotImplemented:{ResultType char[]}{TypedText @encode}{LeftParen (}{Placeholder type-name}{RightParen )}
 // CHECK-CC2: NotImplemented:{TypedText _Bool}
 // CHECK-CC2: VarDecl:{ResultType A *}{TypedText a}
Index: test/Index/complete-objc-message.m
===================================================================
--- test/Index/complete-objc-message.m
+++ test/Index/complete-objc-message.m
@@ -218,13 +218,13 @@
 // CHECK-CC2-NEXT: Container Kind: ObjCInterfaceDecl
 // CHECK-CC2-NEXT: Container is complete
 // CHECK-CC2-NEXT: Container USR: c:objc(cs)Foo
-// RUN: c-index-test -code-completion-at=%s:61:16 %s | FileCheck -check-prefix=CHECK-CC3 %s
+// RUN: c-index-test -code-completion-at=%s:61:17 %s | FileCheck -check-prefix=CHECK-CC3 %s
 // CHECK-CC3: ObjCClassMethodDecl:{ResultType int}{TypedText MyClassMethod:}{Placeholder (id)}
 // CHECK-CC3: ObjCClassMethodDecl:{ResultType int}{TypedText MyPrivateMethod}
-// RUN: c-index-test -code-completion-at=%s:65:16 %s | FileCheck -check-prefix=CHECK-CC4 %s
+// RUN: c-index-test -code-completion-at=%s:65:17 %s | FileCheck -check-prefix=CHECK-CC4 %s
 // CHECK-CC4: ObjCInstanceMethodDecl:{ResultType int}{TypedText MyInstMethod:}{Placeholder (id)}{HorizontalSpace  }{TypedText second:}{Placeholder (id)}
 // CHECK-CC4: ObjCInstanceMethodDecl:{ResultType int}{TypedText MyPrivateInstMethod}
-// RUN: c-index-test -code-completion-at=%s:74:9 %s | FileCheck -check-prefix=CHECK-CC5 %s
+// RUN: c-index-test -code-completion-at=%s:74:10 %s | FileCheck -check-prefix=CHECK-CC5 %s
 // CHECK-CC5: ObjCInstanceMethodDecl:{ResultType int}{TypedText MyInstMethod:}{Placeholder (id)}{HorizontalSpace  }{TypedText second:}{Placeholder (id)}
 // CHECK-CC5: ObjCInstanceMethodDecl:{ResultType int}{TypedText MySubInstMethod}
 // RUN: c-index-test -code-completion-at=%s:82:8 %s | FileCheck -check-prefix=CHECK-CC6 %s
@@ -311,7 +311,7 @@
 // CHECK-CCI: ObjCInstanceMethodDecl:{ResultType void}{TypedText method1} (37)
 // CHECK-CCI: ObjCInstanceMethodDecl:{ResultType void}{TypedText method2} (35)
 
-// RUN: c-index-test -code-completion-at=%s:150:5 %s | FileCheck -check-prefix=CHECK-REDUNDANT %s
+// RUN: c-index-test -code-completion-at=%s:150:6 %s | FileCheck -check-prefix=CHECK-REDUNDANT %s
 // CHECK-REDUNDANT: ObjCInstanceMethodDecl:{ResultType void}{TypedText method2} (35)
 // CHECK-REDUNDANT-NOT: ObjCInstanceMethodDecl:{ResultType void}{TypedText method2}
 // CHECK-REDUNDANT: ObjCInstanceMethodDecl:{ResultType void}{TypedText method3} (35)
Index: test/Index/complete-objc-message-id.m
===================================================================
--- test/Index/complete-objc-message-id.m
+++ test/Index/complete-objc-message-id.m
@@ -68,7 +68,7 @@
 // CHECK-SELECTOR-PREF: ObjCClassMethodDecl:{ResultType id}{TypedText new} (35)
 // CHECK-SELECTOR-PREF: ObjCClassMethodDecl:{ResultType Class}{TypedText superclass} (35)
 
-// RUN: c-index-test -code-completion-at=%s:46:7 %s | FileCheck -check-prefix=CHECK-INSTANCE-QUAL-ID %s
-// RUN: c-index-test -code-completion-at=%s:47:7 %s | FileCheck -check-prefix=CHECK-INSTANCE-QUAL-ID %s
+// RUN: c-index-test -code-completion-at=%s:46:8 %s | FileCheck -check-prefix=CHECK-INSTANCE-QUAL-ID %s
+// RUN: c-index-test -code-completion-at=%s:47:8 %s | FileCheck -check-prefix=CHECK-INSTANCE-QUAL-ID %s
 // CHECK-INSTANCE-QUAL-ID: ObjCInstanceMethodDecl:{ResultType int}{TypedText P1_method1} (37)
 // CHECK-INSTANCE-QUAL-ID: ObjCInstanceMethodDecl:{ResultType int}{TypedText P2_method1} (35)
Index: test/Index/complete-method-decls.m
===================================================================
--- test/Index/complete-method-decls.m
+++ test/Index/complete-method-decls.m
@@ -195,7 +195,7 @@
 // CHECK-CCG: NotImplemented:{TypedText void} (50)
 // CHECK-CCG: NotImplemented:{TypedText volatile} (50)
 // RUN: c-index-test -code-completion-at=%s:60:24 %s | FileCheck -check-prefix=CHECK-CCF %s
-// RUN: c-index-test -code-completion-at=%s:60:26 %s | FileCheck -check-prefix=CHECK-CCH %s
+// RUN: c-index-test -code-completion-at=%s:60:27 %s | FileCheck -check-prefix=CHECK-CCH %s
 // CHECK-CCH: ObjCInterfaceDecl:{TypedText A} (50)
 // CHECK-CCH: ObjCInterfaceDecl:{TypedText B} (50)
 // CHECK-CCH: NotImplemented:{TypedText bycopy} (40)
Index: test/CodeCompletion/objc-message.mm
===================================================================
--- test/CodeCompletion/objc-message.mm
+++ test/CodeCompletion/objc-message.mm
@@ -38,9 +38,9 @@
   [ptr instanceMethod1];
 }
 
-// RUN: %clang_cc1 -fsyntax-only -std=c++11 -code-completion-at=%s:33:7 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -code-completion-at=%s:33:8 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
 // CHECK-CC1: categoryInstanceMethod : [#id#]categoryInstanceMethod
 // CHECK-CC1: instanceMethod1 : [#id#]instanceMethod1
 // CHECK-CC1: protocolInstanceMethod : [#id#]protocolInstanceMethod
-// RUN: %clang_cc1 -fsyntax-only -std=c++11 -code-completion-at=%s:38:7 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -code-completion-at=%s:38:8 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s
 // CHECK-CC2: protocolInstanceMethod : [#id#]protocolInstanceMethod
Index: test/CodeCompletion/filter-ordinary-name.cpp
===================================================================
--- /dev/null
+++ test/CodeCompletion/filter-ordinary-name.cpp
@@ -0,0 +1,8 @@
+int main() {
+int myVariableOne;
+int myVariableTwo;
+myVariableOne;
+// RUN: %clang_cc1 -code-completion-at=%s:4:5 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: COMPLETION: myVariableOne : [#int#]myVariableOne
+// CHECK-CC1-NEXT: COMPLETION: myVariableTwo : [#int#]myVariableTwo
+}
Index: test/CodeCompletion/filter-namespace.cpp
===================================================================
--- /dev/null
+++ test/CodeCompletion/filter-namespace.cpp
@@ -0,0 +1,9 @@
+namespace outerspace {
+  namespace innerspace { }
+}
+using namespace outerspace;
+// RUN: %clang_cc1 -code-completion-at=%s:4:23 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: COMPLETION: outerspace : outerspace
+using namespace outerspace::innerspace;
+// RUN: %clang_cc1 -code-completion-at=%s:7:34 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: COMPLETION: innerspace : innerspace
Index: test/CodeCompletion/filter-member-access.cpp
===================================================================
--- /dev/null
+++ test/CodeCompletion/filter-member-access.cpp
@@ -0,0 +1,28 @@
+class MyClass {
+private:
+int anInteger;
+double aDouble;
+
+public:
+MyClass(int i, double d) {
+anInteger = i;
+aDouble = d;
+}
+int getInt() { return anInteger; }
+double getDouble() { return aDouble; }
+void setInt(int value) { anInteger = value; }
+void setDouble(double value) { aDouble = value; }
+};
+
+int main() {
+MyClass* objectMyClass = new MyClass(5, 1.0);
+objectMyClass->setDouble(5.0);
+objectMyClass->setInt(objectMyClass->getInt());
+// RUN: %clang_cc1 -code-completion-at=%s:19:19 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: COMPLETION: setDouble : [#void#]setDouble(<#double value#>)
+// CHECK-CC1-NEXT: COMPLETION: setInt : [#void#]setInt(<#int value#>)
+// RUN: %clang_cc1 -code-completion-at=%s:20:41 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: COMPLETION: getDouble : [#double#]getDouble()
+// CHECK-CC2-NEXT: COMPLETION: getInt : [#int#]getInt()
+return 0;
+}
Index: test/CodeCompletion/filter-function-name.cpp
===================================================================
--- /dev/null
+++ test/CodeCompletion/filter-function-name.cpp
@@ -0,0 +1,12 @@
+void myFunction();
+
+int main() {
+  myFunction();
+  int var = 0;
+  myFunction();
+  // RUN: %clang_cc1 -code-completion-at=%s:4:8 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
+  // CHECK-CC1: COMPLETION: myFunction : [#void#]myFunction()
+  // RUN: %clang_cc1 -code-completion-at=%s:6:6 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s
+  // CHECK-CC2: COMPLETION: myFunction : [#void#]myFunction()
+}
+
Index: lib/Sema/CodeCompleteConsumer.cpp
===================================================================
--- lib/Sema/CodeCompleteConsumer.cpp
+++ lib/Sema/CodeCompleteConsumer.cpp
@@ -17,6 +17,7 @@
 #include "clang/AST/DeclTemplate.h"
 #include "clang/Sema/Scope.h"
 #include "clang/Sema/Sema.h"
+#include "clang/Lex/Preprocessor.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/Twine.h"
@@ -428,15 +429,39 @@
 
 CodeCompleteConsumer::~CodeCompleteConsumer() { }
 
+bool PrintingCodeCompleteConsumer::isResultFilteredOut(StringRef Filter,
+                                                CodeCompletionResult Result) {
+  switch (Result.Kind) {
+  case CodeCompletionResult::RK_Declaration: {
+    return !(Result.Declaration->getIdentifier() &&
+            Result.Declaration->getIdentifier()->getName().startswith(Filter));
+  }
+  case CodeCompletionResult::RK_Keyword: {
+    return !StringRef(Result.Keyword).startswith(Filter);
+  }
+  case CodeCompletionResult::RK_Macro: {
+    return !Result.Macro->getName().startswith(Filter);
+  }
+  case CodeCompletionResult::RK_Pattern: {
+    return !StringRef(Result.Pattern->getAsString()).startswith(Filter);
+  }
+  default: llvm_unreachable("Unknown code completion result Kind.");
+  }
+}
+
 void 
 PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
                                                  CodeCompletionContext Context,
                                                  CodeCompletionResult *Results,
                                                          unsigned NumResults) {
   std::stable_sort(Results, Results + NumResults);
   
+  StringRef Filter = SemaRef.getPreprocessor().getCodeCompletionFilter();
+
   // Print the results.
   for (unsigned I = 0; I != NumResults; ++I) {
+    if(!Filter.empty() && isResultFilteredOut(Filter, Results[I]))
+      continue;
     OS << "COMPLETION: ";
     switch (Results[I].Kind) {
     case CodeCompletionResult::RK_Declaration:
Index: lib/Lex/Preprocessor.cpp
===================================================================
--- lib/Lex/Preprocessor.cpp
+++ lib/Lex/Preprocessor.cpp
@@ -744,6 +744,9 @@
     }
   } while (!ReturnedToken);
 
+  if (Result.is(tok::code_completion))
+      setCodeCompletionIdentifierInfo(Result.getIdentifierInfo());
+
   LastTokenWasAt = Result.is(tok::at);
 }
 
Index: lib/Lex/Lexer.cpp
===================================================================
--- lib/Lex/Lexer.cpp
+++ lib/Lex/Lexer.cpp
@@ -1533,7 +1533,15 @@
     // preprocessor, which may macro expand it or something.
     if (II->isHandleIdentifierCase())
       return PP->HandleIdentifier(Result);
-    
+
+    if (II->getTokenID() == tok::identifier && isCodeCompletionPoint(CurPtr)
+        && II->getPPKeywordID() == tok::pp_not_keyword
+        && II->getObjCKeywordID() == tok::objc_not_keyword) {
+      // Return the code-completion token.
+      Result.setKind(tok::code_completion);
+      cutOffLexing();
+      return true;
+    }
     return true;
   }
 
Index: include/clang/Sema/CodeCompleteConsumer.h
===================================================================
--- include/clang/Sema/CodeCompleteConsumer.h
+++ include/clang/Sema/CodeCompleteConsumer.h
@@ -913,6 +913,13 @@
   /// \brief Deregisters and destroys this code-completion consumer.
   virtual ~CodeCompleteConsumer();
 
+  /// \name Code-completion filtering
+  /// \brief Check if the result should be filtered out.
+  virtual bool isResultFilteredOut(StringRef Filter,
+                                   CodeCompletionResult Results) {
+    return false;
+  }
+
   /// \name Code-completion callbacks
   //@{
   /// \brief Process the finalized code-completion results.
@@ -966,6 +973,8 @@
                                  OverloadCandidate *Candidates,
                                  unsigned NumCandidates) override;
 
+  bool isResultFilteredOut(StringRef Filter, CodeCompletionResult Results) override;
+
   CodeCompletionAllocator &getAllocator() override {
     return CCTUInfo.getAllocator();
   }
Index: include/clang/Lex/Preprocessor.h
===================================================================
--- include/clang/Lex/Preprocessor.h
+++ include/clang/Lex/Preprocessor.h
@@ -265,6 +265,10 @@
   /// \brief True if we hit the code-completion point.
   bool CodeCompletionReached;
 
+  /// \brief The code completion token containing the information
+  /// on the stem that is to be code completed.
+  IdentifierInfo *CodeCompletionII;
+
   /// \brief The directory that the main file should be considered to occupy,
   /// if it does not correspond to a real file (as happens when building a
   /// module).
@@ -984,6 +988,19 @@
   /// completion point.
   void CodeCompleteNaturalLanguage();
 
+  /// \brief Set the code completion token for filtering purposes.
+  void setCodeCompletionIdentifierInfo(IdentifierInfo *Filter) {
+    CodeCompletionII = Filter;
+  }
+
+  /// \brief Get the code completion token for filtering purposes.
+  StringRef getCodeCompletionFilter() {
+    StringRef filter = StringRef();
+    if (CodeCompletionII)
+      filter = CodeCompletionII->getName();
+    return filter;
+  }
+
   /// \brief Retrieve the preprocessing record, or NULL if there is no
   /// preprocessing record.
   PreprocessingRecord *getPreprocessingRecord() const { return Record; }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to