ilya-biryukov created this revision.
ilya-biryukov added reviewers: sammccall, aaron.ballman, bkramer, sepavloff.

The example that was broken before (^ designate completion points):

  class Foo {
    Foo() : fie^ld^() {} // no completions were provided here.
    int field;
  };

To fix it we don't cut off lexing after an identifier followed by code
completion token is lexed. Instead we skip the rest of identifier and
continue lexing.
This is consistent with behavior of completion when completion token is
right before the identifier.


Repository:
  rC Clang

https://reviews.llvm.org/D44932

Files:
  lib/Lex/Lexer.cpp
  test/CodeCompletion/ctor-initializer.cpp


Index: test/CodeCompletion/ctor-initializer.cpp
===================================================================
--- test/CodeCompletion/ctor-initializer.cpp
+++ test/CodeCompletion/ctor-initializer.cpp
@@ -58,5 +58,9 @@
   // RUN: %clang_cc1 -fsyntax-only -std=c++98 -code-completion-at=%s:57:9 %s 
-o - | FileCheck -check-prefix=CHECK-CC7 %s
   // RUN: %clang_cc1 -fsyntax-only -std=c++14 -code-completion-at=%s:57:9 %s 
-o - | FileCheck -check-prefix=CHECK-CC7 %s
   // CHECK-CC7: COMPLETION: Pattern : member1(<#args#>
+  // Check in the middle and at the end of identifier too.
+  // RUN: %clang_cc1 -fsyntax-only -std=c++98 -code-completion-at=%s:57:13 %s 
-o - | FileCheck -check-prefix=CHECK-CC8 %s
+  // RUN: %clang_cc1 -fsyntax-only -std=c++98 -code-completion-at=%s:57:16 %s 
-o - | FileCheck -check-prefix=CHECK-CC8 %s
+  // CHECK-CC8: COMPLETION: Pattern : member2(<#args#>
   int member1, member2;
 };
Index: lib/Lex/Lexer.cpp
===================================================================
--- lib/Lex/Lexer.cpp
+++ lib/Lex/Lexer.cpp
@@ -1656,7 +1656,17 @@
         && II->getObjCKeywordID() == tok::objc_not_keyword) {
       // Return the code-completion token.
       Result.setKind(tok::code_completion);
-      cutOffLexing();
+      // Skip the code-completion char and all immediate identifier characters.
+      // This ensures we get consistent behavior when completing at any point 
in
+      // an identifier (i.e. at the start, in the middle, at the end). Note 
that
+      // only simple cases (i.e. [a-zA-Z0-9_]) are supported to keep the code
+      // simpler.
+      assert(*CurPtr == 0 && "Completion character must be 0");
+      ++CurPtr;
+      assert(CurPtr < BufferEnd && "eof at completion point");
+      while (isIdentifierBody(*CurPtr))
+        ++CurPtr;
+      BufferPtr = CurPtr;
       return true;
     }
     return true;


Index: test/CodeCompletion/ctor-initializer.cpp
===================================================================
--- test/CodeCompletion/ctor-initializer.cpp
+++ test/CodeCompletion/ctor-initializer.cpp
@@ -58,5 +58,9 @@
   // RUN: %clang_cc1 -fsyntax-only -std=c++98 -code-completion-at=%s:57:9 %s -o - | FileCheck -check-prefix=CHECK-CC7 %s
   // RUN: %clang_cc1 -fsyntax-only -std=c++14 -code-completion-at=%s:57:9 %s -o - | FileCheck -check-prefix=CHECK-CC7 %s
   // CHECK-CC7: COMPLETION: Pattern : member1(<#args#>
+  // Check in the middle and at the end of identifier too.
+  // RUN: %clang_cc1 -fsyntax-only -std=c++98 -code-completion-at=%s:57:13 %s -o - | FileCheck -check-prefix=CHECK-CC8 %s
+  // RUN: %clang_cc1 -fsyntax-only -std=c++98 -code-completion-at=%s:57:16 %s -o - | FileCheck -check-prefix=CHECK-CC8 %s
+  // CHECK-CC8: COMPLETION: Pattern : member2(<#args#>
   int member1, member2;
 };
Index: lib/Lex/Lexer.cpp
===================================================================
--- lib/Lex/Lexer.cpp
+++ lib/Lex/Lexer.cpp
@@ -1656,7 +1656,17 @@
         && II->getObjCKeywordID() == tok::objc_not_keyword) {
       // Return the code-completion token.
       Result.setKind(tok::code_completion);
-      cutOffLexing();
+      // Skip the code-completion char and all immediate identifier characters.
+      // This ensures we get consistent behavior when completing at any point in
+      // an identifier (i.e. at the start, in the middle, at the end). Note that
+      // only simple cases (i.e. [a-zA-Z0-9_]) are supported to keep the code
+      // simpler.
+      assert(*CurPtr == 0 && "Completion character must be 0");
+      ++CurPtr;
+      assert(CurPtr < BufferEnd && "eof at completion point");
+      while (isIdentifierBody(*CurPtr))
+        ++CurPtr;
+      BufferPtr = CurPtr;
       return true;
     }
     return true;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to