CrisCristescu updated this revision to Diff 51404.
CrisCristescu added a comment.

The code_completion token now stores the information, if there is one,
about the identifier that it is lexing.
During the parsing there is a common entry point which is ConsumerToken
where we can set the information necessary for filtering in the Sema
in the case of a code_completion token.
The information is retrieved when doing the actual filtering.

This introduces a change in functionality which means that some tests
had to be modified(6 tests for ObjC) due to the fact that if you press
tab at the end of a word which could be a language specific keyword,
you will get the possible completions of this identifier,
not what could be written after the space. This is in accordance with the
behaviour of IDEs, for instance XCode.
As an example:
const<TAB> will only give completions for variables like constVar,
and if you have const<SPACE><TAB> the you get the possible completions:
const double, const int etc.


Repository:
  rL LLVM

http://reviews.llvm.org/D17820

Files:
  include/clang/Parse/Parser.h
  include/clang/Sema/CodeCompleteConsumer.h
  include/clang/Sema/Sema.h
  lib/Lex/Lexer.cpp
  lib/Sema/CodeCompleteConsumer.cpp
  lib/Sema/Sema.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,7 +60,7 @@
 // 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
@@ -69,7 +69,7 @@
 
 // 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: lib/Sema/Sema.cpp
===================================================================
--- lib/Sema/Sema.cpp
+++ lib/Sema/Sema.cpp
@@ -77,7 +77,7 @@
     isMultiplexExternalSource(false), FPFeatures(pp.getLangOpts()),
     LangOpts(pp.getLangOpts()), PP(pp), Context(ctxt), Consumer(consumer),
     Diags(PP.getDiagnostics()), SourceMgr(PP.getSourceManager()),
-    CollectStats(false), CodeCompleter(CodeCompleter),
+    CollectStats(false), CodeCompleter(CodeCompleter), CodeCompleteFilter(0),
     CurContext(nullptr), OriginalLexicalContext(nullptr),
     PackContext(nullptr), MSStructPragmaOn(false),
     MSPointerToMemberRepresentationMethod(
Index: lib/Sema/CodeCompleteConsumer.cpp
===================================================================
--- lib/Sema/CodeCompleteConsumer.cpp
+++ lib/Sema/CodeCompleteConsumer.cpp
@@ -428,6 +428,28 @@
 
 CodeCompleteConsumer::~CodeCompleteConsumer() { }
 
+bool PrintingCodeCompleteConsumer::isResultFilteredOut(StringRef Filter,
+                                                CodeCompletionResult Result) {
+  switch (Result.Kind) {
+  case CodeCompletionResult::RK_Declaration: {
+    return !(Result.Declaration &&
+            (*Result.Declaration).getIdentifier() &&
+            (*Result.Declaration).getIdentifier()->getName().startswith(Filter));
+  }
+  case CodeCompletionResult::RK_Keyword: {
+    return !(Result.Keyword && StringRef(&(*Result.Keyword)).startswith(Filter));
+  }
+  case CodeCompletionResult::RK_Macro: {
+    return !(Result.Macro && Result.Macro->getName().startswith(Filter));
+  }
+  case CodeCompletionResult::RK_Pattern: {
+    return !(Result.Pattern &&
+             StringRef((Result.Pattern->getAsString())).startswith(Filter));
+  }
+  }
+  return false;
+}
+
 void 
 PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
                                                  CodeCompletionContext Context,
@@ -435,8 +457,12 @@
                                                          unsigned NumResults) {
   std::stable_sort(Results, Results + NumResults);
   
+  StringRef Filter = SemaRef.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/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/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -305,6 +305,9 @@
   /// \brief Code-completion consumer.
   CodeCompleteConsumer *CodeCompleter;
 
+  /// \brief Code-complete filter.
+  IdentifierInfo *CodeCompleteFilter;
+
   /// CurContext - This is the current declaration context of parsing.
   DeclContext *CurContext;
 
@@ -8962,6 +8965,15 @@
     PCC_LocalDeclarationSpecifiers
   };
 
+  void setCodeCompletionFilter(IdentifierInfo* filterII) {
+    CodeCompleteFilter = filterII;
+  }
+  StringRef getCodeCompletionFilter() {
+    if (CodeCompleteFilter)
+      return CodeCompleteFilter->getName();
+    return StringRef();
+  }
+
   void CodeCompleteModuleImport(SourceLocation ImportLoc, ModuleIdPath Path);
   void CodeCompleteOrdinaryName(Scope *S,
                                 ParserCompletionContext CompletionContext);
Index: include/clang/Sema/CodeCompleteConsumer.h
===================================================================
--- include/clang/Sema/CodeCompleteConsumer.h
+++ include/clang/Sema/CodeCompleteConsumer.h
@@ -912,6 +912,14 @@
   /// \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 true;
+  }
+
   /// \name Code-completion callbacks
   //@{
   /// \brief Process the finalized code-completion results.
@@ -965,6 +973,8 @@
                                  OverloadCandidate *Candidates,
                                  unsigned NumCandidates) override;
 
+  bool isResultFilteredOut(StringRef Filter, CodeCompletionResult Results) override;
+
   CodeCompletionAllocator &getAllocator() override {
     return CCTUInfo.getAllocator();
   }
Index: include/clang/Parse/Parser.h
===================================================================
--- include/clang/Parse/Parser.h
+++ include/clang/Parse/Parser.h
@@ -290,6 +290,8 @@
            "Should consume special tokens with Consume*Token");
     PrevTokLocation = Tok.getLocation();
     PP.Lex(Tok);
+    if (Tok.is(tok::code_completion))
+      Actions.setCodeCompletionFilter(Tok.getIdentifierInfo());
     return PrevTokLocation;
   }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • Re: [PATCH] D17820: Clang Code C... Bianca-Cristina Cristescu via cfe-commits

Reply via email to