[PATCH] D31328: [clangd] Add code completion support

2017-04-04 Thread Krasimir Georgiev via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL299421: [clangd] Add code completion support (authored by 
krasimir).

Changed prior to commit:
  https://reviews.llvm.org/D31328?vs=92948&id=94026#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D31328

Files:
  clang-tools-extra/trunk/clangd/ASTManager.cpp
  clang-tools-extra/trunk/clangd/ASTManager.h
  clang-tools-extra/trunk/clangd/ClangDMain.cpp
  clang-tools-extra/trunk/clangd/Protocol.cpp
  clang-tools-extra/trunk/clangd/Protocol.h
  clang-tools-extra/trunk/clangd/ProtocolHandlers.cpp
  clang-tools-extra/trunk/clangd/ProtocolHandlers.h
  clang-tools-extra/trunk/test/clangd/completion.test
  clang-tools-extra/trunk/test/clangd/formatting.test

Index: clang-tools-extra/trunk/clangd/Protocol.cpp
===
--- clang-tools-extra/trunk/clangd/Protocol.cpp
+++ clang-tools-extra/trunk/clangd/Protocol.cpp
@@ -570,3 +570,75 @@
   }
   return Result;
 }
+
+llvm::Optional
+TextDocumentPositionParams::parse(llvm::yaml::MappingNode *Params) {
+  TextDocumentPositionParams Result;
+  for (auto &NextKeyValue : *Params) {
+auto *KeyString = dyn_cast(NextKeyValue.getKey());
+if (!KeyString)
+  return llvm::None;
+
+llvm::SmallString<10> KeyStorage;
+StringRef KeyValue = KeyString->getValue(KeyStorage);
+auto *Value =
+dyn_cast_or_null(NextKeyValue.getValue());
+if (!Value)
+  return llvm::None;
+
+llvm::SmallString<10> Storage;
+if (KeyValue == "textDocument") {
+  auto Parsed = TextDocumentIdentifier::parse(Value);
+  if (!Parsed)
+return llvm::None;
+  Result.textDocument = std::move(*Parsed);
+} else if (KeyValue == "position") {
+  auto Parsed = Position::parse(Value);
+  if (!Parsed)
+return llvm::None;
+  Result.position = std::move(*Parsed);
+} else {
+  return llvm::None;
+}
+  }
+  return Result;
+}
+
+std::string CompletionItem::unparse(const CompletionItem &CI) {
+  std::string Result = "{";
+  llvm::raw_string_ostream Os(Result);
+  assert(!CI.label.empty() && "completion item label is required");
+  Os << R"("label":")" << llvm::yaml::escape(CI.label) << R"(",)";
+  if (CI.kind != CompletionItemKind::Missing)
+Os << R"("kind":)" << static_cast(CI.kind) << R"(",)";
+  if (!CI.detail.empty())
+Os << R"("detail":")" << llvm::yaml::escape(CI.detail) << R"(",)";
+  if (!CI.documentation.empty())
+Os << R"("documentation":")" << llvm::yaml::escape(CI.documentation)
+   << R"(",)";
+  if (!CI.sortText.empty())
+Os << R"("sortText":")" << llvm::yaml::escape(CI.sortText) << R"(",)";
+  if (!CI.filterText.empty())
+Os << R"("filterText":")" << llvm::yaml::escape(CI.filterText) << R"(",)";
+  if (!CI.insertText.empty())
+Os << R"("insertText":")" << llvm::yaml::escape(CI.insertText) << R"(",)";
+  if (CI.insertTextFormat != InsertTextFormat::Missing) {
+Os << R"("insertTextFormat":")" << static_cast(CI.insertTextFormat)
+   << R"(",)";
+  }
+  if (CI.textEdit)
+Os << R"("textEdit":)" << TextEdit::unparse(*CI.textEdit) << ',';
+  if (!CI.additionalTextEdits.empty()) {
+Os << R"("additionalTextEdits":[)";
+for (const auto &Edit : CI.additionalTextEdits)
+  Os << TextEdit::unparse(Edit) << ",";
+Os.flush();
+// The list additionalTextEdits is guaranteed nonempty at this point.
+// Replace the trailing comma with right brace.
+Result.back() = ']';
+  }
+  Os.flush();
+  // Label is required, so Result is guaranteed to have a trailing comma.
+  Result.back() = '}';
+  return Result;
+}
Index: clang-tools-extra/trunk/clangd/ClangDMain.cpp
===
--- clang-tools-extra/trunk/clangd/ClangDMain.cpp
+++ clang-tools-extra/trunk/clangd/ClangDMain.cpp
@@ -61,6 +61,8 @@
   llvm::make_unique(Out, Store));
   Dispatcher.registerHandler("textDocument/codeAction",
  llvm::make_unique(Out, AST));
+  Dispatcher.registerHandler("textDocument/completion",
+ llvm::make_unique(Out, AST));
 
   while (std::cin.good()) {
 // A Language Server Protocol message starts with a HTTP header, delimited
Index: clang-tools-extra/trunk/clangd/ProtocolHandlers.h
===
--- clang-tools-extra/trunk/clangd/ProtocolHandlers.h
+++ clang-tools-extra/trunk/clangd/ProtocolHandlers.h
@@ -36,7 +36,8 @@
   "documentFormattingProvider": true,
   "documentRangeFormattingProvider": true,
   "documentOnTypeFormattingProvider": {"firstTriggerCharacter":"}","moreTriggerCharacter":[]},
-  "codeActionProvider": true
+  "codeActionProvider": true,
+  "completionProvider": {"resolveProvider": false, "triggerCharacters": [".",">"]}
 }}})");
   }
 };
@@ -114,6 +115,16 @@
   ASTManager &AST;
 };
 
+struct CompletionH

[PATCH] D31328: [clangd] Add code completion support

2017-04-02 Thread Stanislav Ionascu via Phabricator via cfe-commits
stanionascu added inline comments.



Comment at: clangd/Protocol.cpp:613
+  if (CI.kind != CompletionItemKind::Missing)
+Os << R"("kind":)" << static_cast(CI.kind) << R"(",)";
+  if (!CI.detail.empty())

if kind is actually provided there will be a trailing quote, as in ("kind": 4").


https://reviews.llvm.org/D31328



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31328: [clangd] Add code completion support

2017-03-30 Thread Benjamin Kramer via Phabricator via cfe-commits
bkramer accepted this revision.
bkramer added a comment.

lg


https://reviews.llvm.org/D31328



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31328: [clangd] Add code completion support

2017-03-27 Thread Marc-Andre Laperle via Phabricator via cfe-commits
malaperle-ericsson added a comment.

Ideas/Observations:

- One thing I has done in my version is to introduce "ASTUnitRunnable", a 
lambda function type that has an ASTUnit as parameter and is executed by the 
ASTManager. So the ASTManager takes care of locking the AST but the actual code 
using the AST is kept in the ProtocolHandlers. I think this can be refactored 
later if this is seen as a good approach.
- I have noticed while testing that there is some wrong escaping happening. I 
had typed "รน" by mistake (french keyboard layout!) and it threw an error about 
unexpected \x. I think using yaml::escape is not entirely correct. This can be 
addressed in a different patch because it affects other protocol handlers as 
well (diagnostics, etc).
- I noticed that "file://" is stripped from file:///path but not "file:" in 
file:/path, I think it's the Eclipse client that's wrong here.

But I don't see any immediate need to change anything in this patch.


https://reviews.llvm.org/D31328



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31328: [clangd] Add code completion support

2017-03-27 Thread Marc-Andre Laperle via Phabricator via cfe-commits
malaperle-ericsson added inline comments.



Comment at: test/clangd/formatting.test:14
+# CHECK:   "codeActionProvider": true,
+# CHECK:   "completionProvider": {"resolveProvider": false, 
"triggerCharacters": [".",">"]}
 # CHECK: }}}

It would be good eventually to trigger on "::"  (static members, etc)


https://reviews.llvm.org/D31328



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31328: [clangd] Add code completion support

2017-03-24 Thread Krasimir Georgiev via Phabricator via cfe-commits
krasimir updated this revision to Diff 92948.
krasimir added a comment.

- Make Items ownership more explicit


https://reviews.llvm.org/D31328

Files:
  clangd/ASTManager.cpp
  clangd/ASTManager.h
  clangd/ClangDMain.cpp
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/completion.test
  test/clangd/formatting.test

Index: test/clangd/formatting.test
===
--- test/clangd/formatting.test
+++ test/clangd/formatting.test
@@ -4,13 +4,14 @@
 Content-Length: 125
 
 {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
-# CHECK: Content-Length: 332
+# CHECK: Content-Length: 424
 # CHECK: {"jsonrpc":"2.0","id":0,"result":{"capabilities":{
 # CHECK:   "textDocumentSync": 1,
 # CHECK:   "documentFormattingProvider": true,
 # CHECK:   "documentRangeFormattingProvider": true,
 # CHECK:   "documentOnTypeFormattingProvider": {"firstTriggerCharacter":"}","moreTriggerCharacter":[]},
-# CHECK:   "codeActionProvider": true
+# CHECK:   "codeActionProvider": true,
+# CHECK:   "completionProvider": {"resolveProvider": false, "triggerCharacters": [".",">"]}
 # CHECK: }}}
 #
 Content-Length: 193
Index: test/clangd/completion.test
===
--- /dev/null
+++ test/clangd/completion.test
@@ -0,0 +1,69 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 208
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#include \nint main() {\n  std::vector v;\n  v.\n}\n"}}}
+
+Content-Length: 148
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/completion","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":3,"character":4}}}
+# The order of results returned by ASTUnit CodeComplete seems to be
+# nondeterministic, so we check regardless of order.
+#
+# CHECK: {"jsonrpc":"2.0","id":1,"result":[
+# CHECK-DAG: {"label":"_M_allocate"}
+# CHECK-DAG: {"label":"_M_allocate_and_copy"}
+# CHECK-DAG: {"label":"_M_assign_aux"}
+# CHECK-DAG: {"label":"_M_assign_dispatch"}
+# CHECK-DAG: {"label":"_M_check_len"}
+# CHECK-DAG: {"label":"_M_create_storage"
+# CHECK-DAG: {"label":"_M_deallocate"}
+# CHECK-DAG: {"label":"_M_erase_at_end"}
+# CHECK-DAG: {"label":"_M_fill_assign"}
+# CHECK-DAG: {"label":"_M_fill_initialize"}
+# CHECK-DAG: {"label":"_M_fill_insert"}
+# CHECK-DAG: {"label":"_M_get_Tp_allocator"}
+# CHECK-DAG: {"label":"_M_impl"}
+# CHECK-DAG: {"label":"_M_initialize_dispatch"}
+# CHECK-DAG: {"label":"_M_insert_aux"}
+# CHECK-DAG: {"label":"_M_insert_dispatch"}
+# CHECK-DAG: {"label":"_M_range_check"}
+# CHECK-DAG: {"label":"_M_range_initialize"}
+# CHECK-DAG: {"label":"_M_range_insert"}
+# CHECK-DAG: {"label":"_Vector_base"}
+# CHECK-DAG: {"label":"assign"}
+# CHECK-DAG: {"label":"at"}
+# CHECK-DAG: {"label":"back"}
+# CHECK-DAG: {"label":"begin"}
+# CHECK-DAG: {"label":"capacity"}
+# CHECK-DAG: {"label":"clear"}
+# CHECK-DAG: {"label":"data"}
+# CHECK-DAG: {"label":"empty"}
+# CHECK-DAG: {"label":"end"}
+# CHECK-DAG: {"label":"erase"}
+# CHECK-DAG: {"label":"front"}
+# CHECK-DAG: {"label":"get_allocator"}
+# CHECK-DAG: {"label":"insert"}
+# CHECK-DAG: {"label":"max_size"}
+# CHECK-DAG: {"label":"operator="}
+# CHECK-DAG: {"label":"operator[]"}
+# CHECK-DAG: {"label":"pop_back"}
+# CHECK-DAG: {"label":"push_back"}
+# CHECK-DAG: {"label":"rbegin"}
+# CHECK-DAG: {"label":"rend"}
+# CHECK-DAG: {"label":"reserve"}
+# CHECK-DAG: {"label":"resize"}
+# CHECK-DAG: {"label":"size"}
+# CHECK-DAG: {"label":"swap"}
+# CHECK-DAG: {"label":"vector"}
+# CHECK-DAG: {"label":"~_Vector_base"}
+# CHECK-DAG: {"label":"~vector"}
+# CHECK: ]}
+Content-Length: 44
+
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
Index: clangd/ProtocolHandlers.h
===
--- clangd/ProtocolHandlers.h
+++ clangd/ProtocolHandlers.h
@@ -36,7 +36,8 @@
   "documentFormattingProvider": true,
   "documentRangeFormattingProvider": true,
   "documentOnTypeFormattingProvider": {"firstTriggerCharacter":"}","moreTriggerCharacter":[]},
-  "codeActionProvider": true
+  "codeActionProvider": true,
+  "completionProvider": {"resolveProvider": false, "triggerCharacters": [".",">"]}
 }}})");
   }
 };
@@ -114,6 +115,16 @@
   ASTManager &AST;
 };
 
+struct CompletionHandler : Handler {
+  CompletionHandler(JSONOutput &Output, ASTManager &AST)
+  : Handler(Output), AST(AST) {}
+
+  void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override;
+
+ private:
+  ASTManager &AST;
+};
+
 }

[PATCH] D31328: [clangd] Add code completion support

2017-03-24 Thread Marc-Andre Laperle via Phabricator via cfe-commits
malaperle-ericsson added a comment.

Urg, I was working on this too :) I'll compare implementations and provide 
comments if I find anything good to suggest.


https://reviews.llvm.org/D31328



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31328: [clangd] Add code completion support

2017-03-24 Thread Krasimir Georgiev via Phabricator via cfe-commits
krasimir updated this revision to Diff 92940.
krasimir marked 7 inline comments as done.
krasimir added a comment.

- Address review comments


https://reviews.llvm.org/D31328

Files:
  clangd/ASTManager.cpp
  clangd/ASTManager.h
  clangd/ClangDMain.cpp
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/completion.test
  test/clangd/formatting.test

Index: test/clangd/formatting.test
===
--- test/clangd/formatting.test
+++ test/clangd/formatting.test
@@ -4,13 +4,14 @@
 Content-Length: 125
 
 {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
-# CHECK: Content-Length: 332
+# CHECK: Content-Length: 424
 # CHECK: {"jsonrpc":"2.0","id":0,"result":{"capabilities":{
 # CHECK:   "textDocumentSync": 1,
 # CHECK:   "documentFormattingProvider": true,
 # CHECK:   "documentRangeFormattingProvider": true,
 # CHECK:   "documentOnTypeFormattingProvider": {"firstTriggerCharacter":"}","moreTriggerCharacter":[]},
-# CHECK:   "codeActionProvider": true
+# CHECK:   "codeActionProvider": true,
+# CHECK:   "completionProvider": {"resolveProvider": false, "triggerCharacters": [".",">"]}
 # CHECK: }}}
 #
 Content-Length: 193
Index: test/clangd/completion.test
===
--- /dev/null
+++ test/clangd/completion.test
@@ -0,0 +1,69 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 208
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#include \nint main() {\n  std::vector v;\n  v.\n}\n"}}}
+
+Content-Length: 148
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/completion","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":3,"character":4}}}
+# The order of results returned by ASTUnit CodeComplete seems to be
+# nondeterministic, so we check regardless of order.
+#
+# CHECK: {"jsonrpc":"2.0","id":1,"result":[
+# CHECK-DAG: {"label":"_M_allocate"}
+# CHECK-DAG: {"label":"_M_allocate_and_copy"}
+# CHECK-DAG: {"label":"_M_assign_aux"}
+# CHECK-DAG: {"label":"_M_assign_dispatch"}
+# CHECK-DAG: {"label":"_M_check_len"}
+# CHECK-DAG: {"label":"_M_create_storage"
+# CHECK-DAG: {"label":"_M_deallocate"}
+# CHECK-DAG: {"label":"_M_erase_at_end"}
+# CHECK-DAG: {"label":"_M_fill_assign"}
+# CHECK-DAG: {"label":"_M_fill_initialize"}
+# CHECK-DAG: {"label":"_M_fill_insert"}
+# CHECK-DAG: {"label":"_M_get_Tp_allocator"}
+# CHECK-DAG: {"label":"_M_impl"}
+# CHECK-DAG: {"label":"_M_initialize_dispatch"}
+# CHECK-DAG: {"label":"_M_insert_aux"}
+# CHECK-DAG: {"label":"_M_insert_dispatch"}
+# CHECK-DAG: {"label":"_M_range_check"}
+# CHECK-DAG: {"label":"_M_range_initialize"}
+# CHECK-DAG: {"label":"_M_range_insert"}
+# CHECK-DAG: {"label":"_Vector_base"}
+# CHECK-DAG: {"label":"assign"}
+# CHECK-DAG: {"label":"at"}
+# CHECK-DAG: {"label":"back"}
+# CHECK-DAG: {"label":"begin"}
+# CHECK-DAG: {"label":"capacity"}
+# CHECK-DAG: {"label":"clear"}
+# CHECK-DAG: {"label":"data"}
+# CHECK-DAG: {"label":"empty"}
+# CHECK-DAG: {"label":"end"}
+# CHECK-DAG: {"label":"erase"}
+# CHECK-DAG: {"label":"front"}
+# CHECK-DAG: {"label":"get_allocator"}
+# CHECK-DAG: {"label":"insert"}
+# CHECK-DAG: {"label":"max_size"}
+# CHECK-DAG: {"label":"operator="}
+# CHECK-DAG: {"label":"operator[]"}
+# CHECK-DAG: {"label":"pop_back"}
+# CHECK-DAG: {"label":"push_back"}
+# CHECK-DAG: {"label":"rbegin"}
+# CHECK-DAG: {"label":"rend"}
+# CHECK-DAG: {"label":"reserve"}
+# CHECK-DAG: {"label":"resize"}
+# CHECK-DAG: {"label":"size"}
+# CHECK-DAG: {"label":"swap"}
+# CHECK-DAG: {"label":"vector"}
+# CHECK-DAG: {"label":"~_Vector_base"}
+# CHECK-DAG: {"label":"~vector"}
+# CHECK: ]}
+Content-Length: 44
+
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
Index: clangd/ProtocolHandlers.h
===
--- clangd/ProtocolHandlers.h
+++ clangd/ProtocolHandlers.h
@@ -36,7 +36,8 @@
   "documentFormattingProvider": true,
   "documentRangeFormattingProvider": true,
   "documentOnTypeFormattingProvider": {"firstTriggerCharacter":"}","moreTriggerCharacter":[]},
-  "codeActionProvider": true
+  "codeActionProvider": true,
+  "completionProvider": {"resolveProvider": false, "triggerCharacters": [".",">"]}
 }}})");
   }
 };
@@ -114,6 +115,16 @@
   ASTManager &AST;
 };
 
+struct CompletionHandler : Handler {
+  CompletionHandler(JSONOutput &Output, ASTManager &AST)
+  : Handler(Output), AST(AST) {}
+
+  void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override;
+
+ priva

[PATCH] D31328: [clangd] Add code completion support

2017-03-24 Thread Krasimir Georgiev via Phabricator via cfe-commits
krasimir updated this revision to Diff 92939.
krasimir added a comment.

- Add '.' and '>' as completion trigger characters


https://reviews.llvm.org/D31328

Files:
  clangd/ASTManager.cpp
  clangd/ASTManager.h
  clangd/ClangDMain.cpp
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/completion.test
  test/clangd/formatting.test

Index: test/clangd/formatting.test
===
--- test/clangd/formatting.test
+++ test/clangd/formatting.test
@@ -4,13 +4,14 @@
 Content-Length: 125
 
 {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
-# CHECK: Content-Length: 332
+# CHECK: Content-Length: 424
 # CHECK: {"jsonrpc":"2.0","id":0,"result":{"capabilities":{
 # CHECK:   "textDocumentSync": 1,
 # CHECK:   "documentFormattingProvider": true,
 # CHECK:   "documentRangeFormattingProvider": true,
 # CHECK:   "documentOnTypeFormattingProvider": {"firstTriggerCharacter":"}","moreTriggerCharacter":[]},
-# CHECK:   "codeActionProvider": true
+# CHECK:   "codeActionProvider": true,
+# CHECK:   "completionProvider": {"resolveProvider": false, "triggerCharacters": [".",">"]}
 # CHECK: }}}
 #
 Content-Length: 193
Index: test/clangd/completion.test
===
--- /dev/null
+++ test/clangd/completion.test
@@ -0,0 +1,69 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 208
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#include \nint main() {\n  std::vector v;\n  v.\n}\n"}}}
+
+Content-Length: 148
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/completion","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":3,"character":4}}}
+# The order of results returned by ASTUnit CodeComplete seems to be
+# nondeterministic, so we check regardless of order.
+#
+# CHECK: {"jsonrpc":"2.0","id":1,"result":[
+# CHECK-DAG: {"label":"_M_allocate"}
+# CHECK-DAG: {"label":"_M_allocate_and_copy"}
+# CHECK-DAG: {"label":"_M_assign_aux"}
+# CHECK-DAG: {"label":"_M_assign_dispatch"}
+# CHECK-DAG: {"label":"_M_check_len"}
+# CHECK-DAG: {"label":"_M_create_storage"
+# CHECK-DAG: {"label":"_M_deallocate"}
+# CHECK-DAG: {"label":"_M_erase_at_end"}
+# CHECK-DAG: {"label":"_M_fill_assign"}
+# CHECK-DAG: {"label":"_M_fill_initialize"}
+# CHECK-DAG: {"label":"_M_fill_insert"}
+# CHECK-DAG: {"label":"_M_get_Tp_allocator"}
+# CHECK-DAG: {"label":"_M_impl"}
+# CHECK-DAG: {"label":"_M_initialize_dispatch"}
+# CHECK-DAG: {"label":"_M_insert_aux"}
+# CHECK-DAG: {"label":"_M_insert_dispatch"}
+# CHECK-DAG: {"label":"_M_range_check"}
+# CHECK-DAG: {"label":"_M_range_initialize"}
+# CHECK-DAG: {"label":"_M_range_insert"}
+# CHECK-DAG: {"label":"_Vector_base"}
+# CHECK-DAG: {"label":"assign"}
+# CHECK-DAG: {"label":"at"}
+# CHECK-DAG: {"label":"back"}
+# CHECK-DAG: {"label":"begin"}
+# CHECK-DAG: {"label":"capacity"}
+# CHECK-DAG: {"label":"clear"}
+# CHECK-DAG: {"label":"data"}
+# CHECK-DAG: {"label":"empty"}
+# CHECK-DAG: {"label":"end"}
+# CHECK-DAG: {"label":"erase"}
+# CHECK-DAG: {"label":"front"}
+# CHECK-DAG: {"label":"get_allocator"}
+# CHECK-DAG: {"label":"insert"}
+# CHECK-DAG: {"label":"max_size"}
+# CHECK-DAG: {"label":"operator="}
+# CHECK-DAG: {"label":"operator[]"}
+# CHECK-DAG: {"label":"pop_back"}
+# CHECK-DAG: {"label":"push_back"}
+# CHECK-DAG: {"label":"rbegin"}
+# CHECK-DAG: {"label":"rend"}
+# CHECK-DAG: {"label":"reserve"}
+# CHECK-DAG: {"label":"resize"}
+# CHECK-DAG: {"label":"size"}
+# CHECK-DAG: {"label":"swap"}
+# CHECK-DAG: {"label":"vector"}
+# CHECK-DAG: {"label":"~_Vector_base"}
+# CHECK-DAG: {"label":"~vector"}
+# CHECK: ]}
+Content-Length: 44
+
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
Index: clangd/ProtocolHandlers.h
===
--- clangd/ProtocolHandlers.h
+++ clangd/ProtocolHandlers.h
@@ -36,7 +36,8 @@
   "documentFormattingProvider": true,
   "documentRangeFormattingProvider": true,
   "documentOnTypeFormattingProvider": {"firstTriggerCharacter":"}","moreTriggerCharacter":[]},
-  "codeActionProvider": true
+  "codeActionProvider": true,
+  "completionProvider": {"resolveProvider": false, "triggerCharacters": [".",">"]}
 }}})");
   }
 };
@@ -114,6 +115,16 @@
   ASTManager &AST;
 };
 
+struct CompletionHandler : Handler {
+  CompletionHandler(JSONOutput &Output, ASTManager &AST)
+  : Handler(Output), AST(AST) {}
+
+  void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override;
+
+ private:
+  ASTManager 

[PATCH] D31328: [clangd] Add code completion support

2017-03-24 Thread Benjamin Kramer via Phabricator via cfe-commits
bkramer added inline comments.



Comment at: clangd/ASTManager.cpp:264
+assert(CCS->getTypedText());
+Item.label = llvm::yaml::escape(CCS->getTypedText());
+if (CCS->getBriefComment())

CompletionItem::unparse should do the escaping. It's weird to have YAML stuff 
here.



Comment at: clangd/ASTManager.cpp:267
+  Item.documentation = llvm::yaml::escape(CCS->getBriefComment());
+Items.push_back(Item);
+  }

std::move



Comment at: clangd/ASTManager.cpp:276
+
+  std::vector getItems() const { return Items; }
+};

I think returning by reference and moving out of CodeCompletionInfo in 
codeComplete() is safe.



Comment at: clangd/ASTManager.h:78
   llvm::StringMap> ASTs;
+  std::mutex ASTLock;
+

Some documentation on the lock would be useful.

I'm a bit worried about the priorities here, code completion should always have 
priority over parsing for diagnostics. But we can address that later.



Comment at: clangd/Protocol.cpp:635
+// flush the stream to the string.
+Os.str();
+// The list additionalTextEdits is guaranteed nonempty at this point.

Os.flush();



Comment at: clangd/Protocol.cpp:640
+  }
+  Os.str();
+  // Label is required, so Result is guaranteed to have a trailing comma.

Os.flush();



Comment at: clangd/Protocol.h:289
+struct CompletionItem {
+  CompletionItem()
+  : kind(CompletionItemKind::Missing),

Just use C++11 inline initialization, no need to spell out the constructor.


https://reviews.llvm.org/D31328



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31328: [clangd] Add code completion support

2017-03-24 Thread Krasimir Georgiev via Phabricator via cfe-commits
krasimir updated this revision to Diff 92931.
krasimir added a comment.

- Clean-up leftovers


https://reviews.llvm.org/D31328

Files:
  clangd/ASTManager.cpp
  clangd/ASTManager.h
  clangd/ClangDMain.cpp
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/completion.test
  test/clangd/formatting.test

Index: test/clangd/formatting.test
===
--- test/clangd/formatting.test
+++ test/clangd/formatting.test
@@ -4,13 +4,14 @@
 Content-Length: 125
 
 {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
-# CHECK: Content-Length: 332
+# CHECK: Content-Length: 392
 # CHECK: {"jsonrpc":"2.0","id":0,"result":{"capabilities":{
 # CHECK:   "textDocumentSync": 1,
 # CHECK:   "documentFormattingProvider": true,
 # CHECK:   "documentRangeFormattingProvider": true,
 # CHECK:   "documentOnTypeFormattingProvider": {"firstTriggerCharacter":"}","moreTriggerCharacter":[]},
-# CHECK:   "codeActionProvider": true
+# CHECK:   "codeActionProvider": true,
+# CHECK:   "completionProvider": {"resolveProvider": false}
 # CHECK: }}}
 #
 Content-Length: 193
Index: test/clangd/completion.test
===
--- /dev/null
+++ test/clangd/completion.test
@@ -0,0 +1,69 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 208
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#include \nint main() {\n  std::vector v;\n  v.\n}\n"}}}
+
+Content-Length: 148
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/completion","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":3,"character":4}}}
+# The order of results returned by ASTUnit CodeComplete seems to be
+# nondeterministic, so we check regardless of order.
+#
+# CHECK: {"jsonrpc":"2.0","id":1,"result":[
+# CHECK-DAG: {"label":"_M_allocate"}
+# CHECK-DAG: {"label":"_M_allocate_and_copy"}
+# CHECK-DAG: {"label":"_M_assign_aux"}
+# CHECK-DAG: {"label":"_M_assign_dispatch"}
+# CHECK-DAG: {"label":"_M_check_len"}
+# CHECK-DAG: {"label":"_M_create_storage"
+# CHECK-DAG: {"label":"_M_deallocate"}
+# CHECK-DAG: {"label":"_M_erase_at_end"}
+# CHECK-DAG: {"label":"_M_fill_assign"}
+# CHECK-DAG: {"label":"_M_fill_initialize"}
+# CHECK-DAG: {"label":"_M_fill_insert"}
+# CHECK-DAG: {"label":"_M_get_Tp_allocator"}
+# CHECK-DAG: {"label":"_M_impl"}
+# CHECK-DAG: {"label":"_M_initialize_dispatch"}
+# CHECK-DAG: {"label":"_M_insert_aux"}
+# CHECK-DAG: {"label":"_M_insert_dispatch"}
+# CHECK-DAG: {"label":"_M_range_check"}
+# CHECK-DAG: {"label":"_M_range_initialize"}
+# CHECK-DAG: {"label":"_M_range_insert"}
+# CHECK-DAG: {"label":"_Vector_base"}
+# CHECK-DAG: {"label":"assign"}
+# CHECK-DAG: {"label":"at"}
+# CHECK-DAG: {"label":"back"}
+# CHECK-DAG: {"label":"begin"}
+# CHECK-DAG: {"label":"capacity"}
+# CHECK-DAG: {"label":"clear"}
+# CHECK-DAG: {"label":"data"}
+# CHECK-DAG: {"label":"empty"}
+# CHECK-DAG: {"label":"end"}
+# CHECK-DAG: {"label":"erase"}
+# CHECK-DAG: {"label":"front"}
+# CHECK-DAG: {"label":"get_allocator"}
+# CHECK-DAG: {"label":"insert"}
+# CHECK-DAG: {"label":"max_size"}
+# CHECK-DAG: {"label":"operator="}
+# CHECK-DAG: {"label":"operator[]"}
+# CHECK-DAG: {"label":"pop_back"}
+# CHECK-DAG: {"label":"push_back"}
+# CHECK-DAG: {"label":"rbegin"}
+# CHECK-DAG: {"label":"rend"}
+# CHECK-DAG: {"label":"reserve"}
+# CHECK-DAG: {"label":"resize"}
+# CHECK-DAG: {"label":"size"}
+# CHECK-DAG: {"label":"swap"}
+# CHECK-DAG: {"label":"vector"}
+# CHECK-DAG: {"label":"~_Vector_base"}
+# CHECK-DAG: {"label":"~vector"}
+# CHECK: ]}
+Content-Length: 44
+
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
Index: clangd/ProtocolHandlers.h
===
--- clangd/ProtocolHandlers.h
+++ clangd/ProtocolHandlers.h
@@ -36,7 +36,8 @@
   "documentFormattingProvider": true,
   "documentRangeFormattingProvider": true,
   "documentOnTypeFormattingProvider": {"firstTriggerCharacter":"}","moreTriggerCharacter":[]},
-  "codeActionProvider": true
+  "codeActionProvider": true,
+  "completionProvider": {"resolveProvider": false}
 }}})");
   }
 };
@@ -114,6 +115,16 @@
   ASTManager &AST;
 };
 
+struct CompletionHandler : Handler {
+  CompletionHandler(JSONOutput &Output, ASTManager &AST)
+  : Handler(Output), AST(AST) {}
+
+  void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override;
+
+ private:
+  ASTManager &AST;
+};
+
 } // namespace clangd
 } // namespace clang
 
Index: clangd/ProtocolHandlers.cpp

[PATCH] D31328: [clangd] Add code completion support

2017-03-24 Thread Krasimir Georgiev via Phabricator via cfe-commits
krasimir created this revision.

Adds code completion support to clangd.


https://reviews.llvm.org/D31328

Files:
  clangd/ASTManager.cpp
  clangd/ASTManager.h
  clangd/ClangDMain.cpp
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/completion.test
  test/clangd/formatting.test

Index: test/clangd/formatting.test
===
--- test/clangd/formatting.test
+++ test/clangd/formatting.test
@@ -4,13 +4,14 @@
 Content-Length: 125
 
 {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
-# CHECK: Content-Length: 332
+# CHECK: Content-Length: 392
 # CHECK: {"jsonrpc":"2.0","id":0,"result":{"capabilities":{
 # CHECK:   "textDocumentSync": 1,
 # CHECK:   "documentFormattingProvider": true,
 # CHECK:   "documentRangeFormattingProvider": true,
 # CHECK:   "documentOnTypeFormattingProvider": {"firstTriggerCharacter":"}","moreTriggerCharacter":[]},
-# CHECK:   "codeActionProvider": true
+# CHECK:   "codeActionProvider": true,
+# CHECK:   "completionProvider": {"resolveProvider": false}
 # CHECK: }}}
 #
 Content-Length: 193
Index: test/clangd/completion.test
===
--- /dev/null
+++ test/clangd/completion.test
@@ -0,0 +1,69 @@
+# RUN: clangd -run-synchronously < %s | FileCheck %s
+# It is absolutely vital that this file has CRLF line endings.
+#
+Content-Length: 125
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+
+Content-Length: 208
+
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#include \nint main() {\n  std::vector v;\n  v.\n}\n"}}}
+
+Content-Length: 148
+
+{"jsonrpc":"2.0","id":1,"method":"textDocument/completion","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":3,"character":4}}}
+# The order of results returned by ASTUnit CodeComplete seems to be
+# nondeterministic, so we check regardless of order.
+#
+# CHECK: {"jsonrpc":"2.0","id":1,"result":[
+# CHECK-DAG: {"label":"_M_allocate"}
+# CHECK-DAG: {"label":"_M_allocate_and_copy"}
+# CHECK-DAG: {"label":"_M_assign_aux"}
+# CHECK-DAG: {"label":"_M_assign_dispatch"}
+# CHECK-DAG: {"label":"_M_check_len"}
+# CHECK-DAG: {"label":"_M_create_storage"
+# CHECK-DAG: {"label":"_M_deallocate"}
+# CHECK-DAG: {"label":"_M_erase_at_end"}
+# CHECK-DAG: {"label":"_M_fill_assign"}
+# CHECK-DAG: {"label":"_M_fill_initialize"}
+# CHECK-DAG: {"label":"_M_fill_insert"}
+# CHECK-DAG: {"label":"_M_get_Tp_allocator"}
+# CHECK-DAG: {"label":"_M_impl"}
+# CHECK-DAG: {"label":"_M_initialize_dispatch"}
+# CHECK-DAG: {"label":"_M_insert_aux"}
+# CHECK-DAG: {"label":"_M_insert_dispatch"}
+# CHECK-DAG: {"label":"_M_range_check"}
+# CHECK-DAG: {"label":"_M_range_initialize"}
+# CHECK-DAG: {"label":"_M_range_insert"}
+# CHECK-DAG: {"label":"_Vector_base"}
+# CHECK-DAG: {"label":"assign"}
+# CHECK-DAG: {"label":"at"}
+# CHECK-DAG: {"label":"back"}
+# CHECK-DAG: {"label":"begin"}
+# CHECK-DAG: {"label":"capacity"}
+# CHECK-DAG: {"label":"clear"}
+# CHECK-DAG: {"label":"data"}
+# CHECK-DAG: {"label":"empty"}
+# CHECK-DAG: {"label":"end"}
+# CHECK-DAG: {"label":"erase"}
+# CHECK-DAG: {"label":"front"}
+# CHECK-DAG: {"label":"get_allocator"}
+# CHECK-DAG: {"label":"insert"}
+# CHECK-DAG: {"label":"max_size"}
+# CHECK-DAG: {"label":"operator="}
+# CHECK-DAG: {"label":"operator[]"}
+# CHECK-DAG: {"label":"pop_back"}
+# CHECK-DAG: {"label":"push_back"}
+# CHECK-DAG: {"label":"rbegin"}
+# CHECK-DAG: {"label":"rend"}
+# CHECK-DAG: {"label":"reserve"}
+# CHECK-DAG: {"label":"resize"}
+# CHECK-DAG: {"label":"size"}
+# CHECK-DAG: {"label":"swap"}
+# CHECK-DAG: {"label":"vector"}
+# CHECK-DAG: {"label":"~_Vector_base"}
+# CHECK-DAG: {"label":"~vector"}
+# CHECK: ]}
+Content-Length: 44
+
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
Index: clangd/ProtocolHandlers.h
===
--- clangd/ProtocolHandlers.h
+++ clangd/ProtocolHandlers.h
@@ -36,7 +36,8 @@
   "documentFormattingProvider": true,
   "documentRangeFormattingProvider": true,
   "documentOnTypeFormattingProvider": {"firstTriggerCharacter":"}","moreTriggerCharacter":[]},
-  "codeActionProvider": true
+  "codeActionProvider": true,
+  "completionProvider": {"resolveProvider": false}
 }}})");
   }
 };
@@ -114,6 +115,16 @@
   ASTManager &AST;
 };
 
+struct CompletionHandler : Handler {
+  CompletionHandler(JSONOutput &Output, ASTManager &AST)
+  : Handler(Output), AST(AST) {}
+
+  void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override;
+
+ private:
+  ASTManager &AST;
+};
+
 } // namespace clangd
 } // namespace clang
 
Index: clangd/ProtocolHandlers.cpp
=