[PATCH] D39836: [clangd] Drop impossible completions (unavailable or inaccessible)

2017-11-23 Thread Sam McCall via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL318925: [clangd] Drop impossible completions (unavailable or 
inaccessible) (authored by sammccall).

Repository:
  rL LLVM

https://reviews.llvm.org/D39836

Files:
  clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp
  clang-tools-extra/trunk/clangd/ClangdLSPServer.h
  clang-tools-extra/trunk/clangd/ClangdServer.cpp
  clang-tools-extra/trunk/clangd/ClangdServer.h
  clang-tools-extra/trunk/clangd/ClangdUnit.cpp
  clang-tools-extra/trunk/clangd/ClangdUnit.h
  clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp
  clang-tools-extra/trunk/test/clangd/completion-items-kinds.test
  clang-tools-extra/trunk/test/clangd/completion-priorities.test
  clang-tools-extra/trunk/test/clangd/completion-qualifiers.test
  clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp

Index: clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp
===
--- clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp
+++ clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp
@@ -788,6 +788,8 @@
   int method();
 
   int field;
+private:
+  int private_field;
 };
 
 int test() {
@@ -828,7 +830,10 @@
   // Class members. The only items that must be present in after-dor
   // completion.
   EXPECT_TRUE(ContainsItem(Results, MethodItemText));
+  EXPECT_TRUE(ContainsItem(Results, MethodItemText));
   EXPECT_TRUE(ContainsItem(Results, "field"));
+  EXPECT_EQ(Opts.IncludeIneligibleResults,
+ContainsItem(Results, "private_field"));
   // Global items.
   EXPECT_FALSE(ContainsItem(Results, "global_var"));
   EXPECT_FALSE(ContainsItem(Results, GlobalFuncItemText));
@@ -889,18 +894,26 @@
 }
   };
 
-  for (bool IncludeMacros : {true, false})
-for (bool IncludeGlobals : {true, false})
-  for (bool IncludeBriefComments : {true, false})
-for (bool EnableSnippets : {true, false})
+  clangd::CodeCompleteOptions CCOpts;
+  for (bool IncludeMacros : {true, false}){
+CCOpts.IncludeMacros = IncludeMacros;
+for (bool IncludeGlobals : {true, false}){
+  CCOpts.IncludeGlobals = IncludeGlobals;
+  for (bool IncludeBriefComments : {true, false}){
+CCOpts.IncludeBriefComments = IncludeBriefComments;
+for (bool EnableSnippets : {true, false}){
+  CCOpts.EnableSnippets = EnableSnippets;
   for (bool IncludeCodePatterns : {true, false}) {
-TestWithOpts(clangd::CodeCompleteOptions(
-/*EnableSnippets=*/EnableSnippets,
-/*IncludeCodePatterns=*/IncludeCodePatterns,
-/*IncludeMacros=*/IncludeMacros,
-/*IncludeGlobals=*/IncludeGlobals,
-/*IncludeBriefComments=*/IncludeBriefComments));
+CCOpts.IncludeCodePatterns = IncludeCodePatterns;
+for (bool IncludeIneligibleResults : {true, false}) {
+  CCOpts.IncludeIneligibleResults = IncludeIneligibleResults;
+  TestWithOpts(CCOpts);
+}
   }
+}
+  }
+}
+  }
 }
 
 class ClangdThreadingTest : public ClangdVFSTest {};
Index: clang-tools-extra/trunk/clangd/ClangdServer.h
===
--- clang-tools-extra/trunk/clangd/ClangdServer.h
+++ clang-tools-extra/trunk/clangd/ClangdServer.h
@@ -182,9 +182,6 @@
   /// AsyncThreadsCount worker threads. However, if \p AsyncThreadsCount is 0,
   /// all requests will be processed on the calling thread.
   ///
-  /// When \p SnippetCompletions is true, completion items will be presented
-  /// with embedded snippets. Otherwise, plaintext items will be presented.
-  ///
   /// ClangdServer uses \p FSProvider to get an instance of vfs::FileSystem for
   /// each parsing request. Results of code completion and diagnostics also
   /// include a tag, that \p FSProvider returns along with the vfs::FileSystem.
@@ -213,7 +210,7 @@
DiagnosticsConsumer ,
FileSystemProvider , unsigned AsyncThreadsCount,
bool StorePreamblesInMemory,
-   clangd::CodeCompleteOptions CodeCompleteOpts,
+   const clangd::CodeCompleteOptions ,
clangd::Logger ,
llvm::Optional ResourceDir = llvm::None);
 
Index: clang-tools-extra/trunk/clangd/ClangdServer.cpp
===
--- clang-tools-extra/trunk/clangd/ClangdServer.cpp
+++ clang-tools-extra/trunk/clangd/ClangdServer.cpp
@@ -169,11 +169,14 @@
 Worker.join();
 }
 
-ClangdServer::ClangdServer(
-GlobalCompilationDatabase , DiagnosticsConsumer ,
-FileSystemProvider , unsigned AsyncThreadsCount,
-bool StorePreamblesInMemory, clangd::CodeCompleteOptions CodeCompleteOpts,
-clangd::Logger , llvm::Optional ResourceDir)
+ClangdServer::ClangdServer(GlobalCompilationDatabase ,
+   

[PATCH] D39836: [clangd] Drop impossible completions (unavailable or inaccessible)

2017-11-23 Thread Sam McCall via Phabricator via cfe-commits
sammccall updated this revision to Diff 124066.
sammccall added a comment.

Address review comments


https://reviews.llvm.org/D39836

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/tool/ClangdMain.cpp
  test/clangd/completion-items-kinds.test
  test/clangd/completion-priorities.test
  test/clangd/completion-qualifiers.test
  unittests/clangd/ClangdTests.cpp

Index: unittests/clangd/ClangdTests.cpp
===
--- unittests/clangd/ClangdTests.cpp
+++ unittests/clangd/ClangdTests.cpp
@@ -788,6 +788,8 @@
   int method();
 
   int field;
+private:
+  int private_field;
 };
 
 int test() {
@@ -828,7 +830,10 @@
   // Class members. The only items that must be present in after-dor
   // completion.
   EXPECT_TRUE(ContainsItem(Results, MethodItemText));
+  EXPECT_TRUE(ContainsItem(Results, MethodItemText));
   EXPECT_TRUE(ContainsItem(Results, "field"));
+  EXPECT_EQ(Opts.IncludeIneligibleResults,
+ContainsItem(Results, "private_field"));
   // Global items.
   EXPECT_FALSE(ContainsItem(Results, "global_var"));
   EXPECT_FALSE(ContainsItem(Results, GlobalFuncItemText));
@@ -889,18 +894,26 @@
 }
   };
 
-  for (bool IncludeMacros : {true, false})
-for (bool IncludeGlobals : {true, false})
-  for (bool IncludeBriefComments : {true, false})
-for (bool EnableSnippets : {true, false})
+  clangd::CodeCompleteOptions CCOpts;
+  for (bool IncludeMacros : {true, false}){
+CCOpts.IncludeMacros = IncludeMacros;
+for (bool IncludeGlobals : {true, false}){
+  CCOpts.IncludeGlobals = IncludeGlobals;
+  for (bool IncludeBriefComments : {true, false}){
+CCOpts.IncludeBriefComments = IncludeBriefComments;
+for (bool EnableSnippets : {true, false}){
+  CCOpts.EnableSnippets = EnableSnippets;
   for (bool IncludeCodePatterns : {true, false}) {
-TestWithOpts(clangd::CodeCompleteOptions(
-/*EnableSnippets=*/EnableSnippets,
-/*IncludeCodePatterns=*/IncludeCodePatterns,
-/*IncludeMacros=*/IncludeMacros,
-/*IncludeGlobals=*/IncludeGlobals,
-/*IncludeBriefComments=*/IncludeBriefComments));
+CCOpts.IncludeCodePatterns = IncludeCodePatterns;
+for (bool IncludeIneligibleResults : {true, false}) {
+  CCOpts.IncludeIneligibleResults = IncludeIneligibleResults;
+  TestWithOpts(CCOpts);
+}
   }
+}
+  }
+}
+  }
 }
 
 class ClangdThreadingTest : public ClangdVFSTest {};
Index: test/clangd/completion-qualifiers.test
===
--- test/clangd/completion-qualifiers.test
+++ test/clangd/completion-qualifiers.test
@@ -13,7 +13,7 @@
 # CHECK-NEXT:  "result": {
 # CHECK-NEXT:"isIncomplete": false,
 # CHECK-NEXT:"items": [
-# Eligible const functions are at the top of the list.
+# Eligible functions are at the top of the list.
 # CHECK-NEXT:  {
 # CHECK-NEXT:"detail": "int",
 # CHECK-NEXT:"filterText": "bar",
@@ -32,18 +32,9 @@
 # CHECK-NEXT:"label": "Foo::foo() const",
 # CHECK-NEXT:"sortText": "37foo"
 # CHECK-NEXT:  },
-# Ineligible non-const function is at the bottom of the list.
-# CHECK-NEXT:  {
-#  CHECK:"detail": "int",
-#  CHECK:"filterText": "foo",
-# CHECK-NEXT:"insertText": "foo",
-# CHECK-NEXT:"insertTextFormat": 1,
-# CHECK-NEXT:"kind": 2,
-# CHECK-NEXT:"label": "foo() const",
-# CHECK-NEXT:"sortText": "200035foo"
-# CHECK-NEXT:  }
-# CHECK-NEXT:]
-# CHECK-NEXT:  }
+# Ineligible private functions are not present.
+#  CHECK-NOT:"label": "foo() const",
+#  CHECK:]
 Content-Length: 44
 
 {"jsonrpc":"2.0","id":4,"method":"shutdown"}
Index: test/clangd/completion-priorities.test
===
--- test/clangd/completion-priorities.test
+++ test/clangd/completion-priorities.test
@@ -61,28 +61,10 @@
 # CHECK-NEXT:"kind": 2,
 # CHECK-NEXT:"label": "pub()",
 # CHECK-NEXT:"sortText": "34pub"
-# CHECK-NEXT:  },
-# priv() and prot() are at the end of the list
-# CHECK-NEXT:  {
-#  CHECK:"detail": "void",
-#  CHECK:"filterText": "priv",
-# CHECK-NEXT:"insertText": "priv",
-# CHECK-NEXT:"insertTextFormat": 1,
-# CHECK-NEXT:"kind": 2,
-# CHECK-NEXT:"label": "priv()",
-# CHECK-NEXT:"sortText": "200034priv"
-# CHECK-NEXT:  },
-# CHECK-NEXT:  {
-# CHECK-NEXT:"detail": "void",
-# CHECK-NEXT:"filterText": "prot",
-# CHECK-NEXT:"insertText": "prot",
-# CHECK-NEXT:"insertTextFormat": 1,
-# CHECK-NEXT:

[PATCH] D39836: [clangd] Drop impossible completions (unavailable or inaccessible)

2017-11-23 Thread Sam McCall via Phabricator via cfe-commits
sammccall added inline comments.



Comment at: clangd/tool/ClangdMain.cpp:169
+  clangd::CodeCompleteOptions CCOpts;
+  CCOpts.EnableSnippets = EnableSnippets;
+  CCOpts.IncludeIneligibleResults = IncludeIneligibleResults;

ilya-biryukov wrote:
> We should also set `IncludeCodePatterns = EnableSnippets` here.  May be worth 
> adding a test that they are in the completion results.
Good catch!
Unfortunately our previous attempt this failed because static_cast is not a 
code pattern (probably it should be).

 - Added a test to completion-items-kinds.
 - Added documentation to the flag to indicate it does this
 - Changed the CodePatterns default to true (equivalent to setting it here, and 
keeps the defaults in one place)
 - set flag defaults based on CompleteOption defaults so they're in one place



https://reviews.llvm.org/D39836



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


[PATCH] D39836: [clangd] Drop impossible completions (unavailable or inaccessible)

2017-11-22 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov added inline comments.



Comment at: clangd/tool/ClangdMain.cpp:169
+  clangd::CodeCompleteOptions CCOpts;
+  CCOpts.EnableSnippets = EnableSnippets;
+  CCOpts.IncludeIneligibleResults = IncludeIneligibleResults;

We should also set `IncludeCodePatterns = EnableSnippets` here.  May be worth 
adding a test that they are in the completion results.


https://reviews.llvm.org/D39836



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


[PATCH] D39836: [clangd] Drop impossible completions (unavailable or inaccessible)

2017-11-21 Thread Sam McCall via Phabricator via cfe-commits
sammccall requested review of this revision.
sammccall added a comment.

PTAL - this is now optional. The results will be hidden by default, but can be 
turned on with a flag.


https://reviews.llvm.org/D39836



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


[PATCH] D39836: [clangd] Drop impossible completions (unavailable or inaccessible)

2017-11-21 Thread Sam McCall via Phabricator via cfe-commits
sammccall updated this revision to Diff 123819.
sammccall added a comment.

(trying to resync the diff to head)


https://reviews.llvm.org/D39836

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/tool/ClangdMain.cpp
  test/clangd/completion-priorities.test
  test/clangd/completion-qualifiers.test
  unittests/clangd/ClangdTests.cpp

Index: unittests/clangd/ClangdTests.cpp
===
--- unittests/clangd/ClangdTests.cpp
+++ unittests/clangd/ClangdTests.cpp
@@ -788,6 +788,8 @@
   int method();
 
   int field;
+private:
+  int private_field;
 };
 
 int test() {
@@ -828,7 +830,10 @@
   // Class members. The only items that must be present in after-dor
   // completion.
   EXPECT_TRUE(ContainsItem(Results, MethodItemText));
+  EXPECT_TRUE(ContainsItem(Results, MethodItemText));
   EXPECT_TRUE(ContainsItem(Results, "field"));
+  EXPECT_EQ(Opts.IncludeIneligibleResults,
+ContainsItem(Results, "private_field"));
   // Global items.
   EXPECT_FALSE(ContainsItem(Results, "global_var"));
   EXPECT_FALSE(ContainsItem(Results, GlobalFuncItemText));
@@ -889,18 +894,26 @@
 }
   };
 
-  for (bool IncludeMacros : {true, false})
-for (bool IncludeGlobals : {true, false})
-  for (bool IncludeBriefComments : {true, false})
-for (bool EnableSnippets : {true, false})
+  clangd::CodeCompleteOptions CCOpts;
+  for (bool IncludeMacros : {true, false}){
+CCOpts.IncludeMacros = IncludeMacros;
+for (bool IncludeGlobals : {true, false}){
+  CCOpts.IncludeGlobals = IncludeGlobals;
+  for (bool IncludeBriefComments : {true, false}){
+CCOpts.IncludeBriefComments = IncludeBriefComments;
+for (bool EnableSnippets : {true, false}){
+  CCOpts.EnableSnippets = EnableSnippets;
   for (bool IncludeCodePatterns : {true, false}) {
-TestWithOpts(clangd::CodeCompleteOptions(
-/*EnableSnippets=*/EnableSnippets,
-/*IncludeCodePatterns=*/IncludeCodePatterns,
-/*IncludeMacros=*/IncludeMacros,
-/*IncludeGlobals=*/IncludeGlobals,
-/*IncludeBriefComments=*/IncludeBriefComments));
+CCOpts.IncludeCodePatterns = IncludeCodePatterns;
+for (bool IncludeIneligibleResults : {true, false}) {
+  CCOpts.IncludeIneligibleResults = IncludeIneligibleResults;
+  TestWithOpts(CCOpts);
+}
   }
+}
+  }
+}
+  }
 }
 
 class ClangdThreadingTest : public ClangdVFSTest {};
Index: test/clangd/completion-qualifiers.test
===
--- test/clangd/completion-qualifiers.test
+++ test/clangd/completion-qualifiers.test
@@ -13,7 +13,7 @@
 # CHECK-NEXT:  "result": {
 # CHECK-NEXT:"isIncomplete": false,
 # CHECK-NEXT:"items": [
-# Eligible const functions are at the top of the list.
+# Eligible functions are at the top of the list.
 # CHECK-NEXT:  {
 # CHECK-NEXT:"detail": "int",
 # CHECK-NEXT:"filterText": "bar",
@@ -32,18 +32,9 @@
 # CHECK-NEXT:"label": "Foo::foo() const",
 # CHECK-NEXT:"sortText": "37foo"
 # CHECK-NEXT:  },
-# Ineligible non-const function is at the bottom of the list.
-# CHECK-NEXT:  {
-#  CHECK:"detail": "int",
-#  CHECK:"filterText": "foo",
-# CHECK-NEXT:"insertText": "foo",
-# CHECK-NEXT:"insertTextFormat": 1,
-# CHECK-NEXT:"kind": 2,
-# CHECK-NEXT:"label": "foo() const",
-# CHECK-NEXT:"sortText": "200035foo"
-# CHECK-NEXT:  }
-# CHECK-NEXT:]
-# CHECK-NEXT:  }
+# Ineligible private functions are not present.
+#  CHECK-NOT:"label": "foo() const",
+#  CHECK:]
 Content-Length: 44
 
 {"jsonrpc":"2.0","id":4,"method":"shutdown"}
Index: test/clangd/completion-priorities.test
===
--- test/clangd/completion-priorities.test
+++ test/clangd/completion-priorities.test
@@ -61,28 +61,10 @@
 # CHECK-NEXT:"kind": 2,
 # CHECK-NEXT:"label": "pub()",
 # CHECK-NEXT:"sortText": "34pub"
-# CHECK-NEXT:  },
-# priv() and prot() are at the end of the list
-# CHECK-NEXT:  {
-#  CHECK:"detail": "void",
-#  CHECK:"filterText": "priv",
-# CHECK-NEXT:"insertText": "priv",
-# CHECK-NEXT:"insertTextFormat": 1,
-# CHECK-NEXT:"kind": 2,
-# CHECK-NEXT:"label": "priv()",
-# CHECK-NEXT:"sortText": "200034priv"
-# CHECK-NEXT:  },
-# CHECK-NEXT:  {
-# CHECK-NEXT:"detail": "void",
-# CHECK-NEXT:"filterText": "prot",
-# CHECK-NEXT:"insertText": "prot",
-# CHECK-NEXT:"insertTextFormat": 1,
-# CHECK-NEXT:"kind": 2,
-# CHECK-NEXT:   

[PATCH] D39836: [clangd] Drop impossible completions (unavailable or inaccessible)

2017-11-21 Thread Sam McCall via Phabricator via cfe-commits
sammccall updated this revision to Diff 123817.
sammccall added a comment.
This revision is now accepted and ready to land.

Add an option to allow impossible completions.
While here, remove 'helpful' constructors that take some subset of the params.


https://reviews.llvm.org/D39836

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/ClangdUnit.cpp
  clangd/ClangdUnit.h
  clangd/JSONExpr.cpp
  clangd/JSONExpr.h
  clangd/tool/ClangdMain.cpp
  test/clangd/completion-priorities.test
  test/clangd/completion-qualifiers.test
  unittests/clangd/ClangdTests.cpp
  unittests/clangd/JSONExprTests.cpp

Index: unittests/clangd/JSONExprTests.cpp
===
--- unittests/clangd/JSONExprTests.cpp
+++ unittests/clangd/JSONExprTests.cpp
@@ -15,6 +15,9 @@
 namespace clang {
 namespace clangd {
 namespace json {
+void PrintTo(const Expr , std::ostream *OS) {
+  llvm::raw_os_ostream(*OS) << llvm::formatv("{0:2}", E);
+}
 namespace {
 
 std::string s(const Expr ) { return llvm::formatv("{0}", E).str(); }
@@ -108,6 +111,77 @@
  }));
 }
 
+TEST(JSONTest, Parse) {
+  auto Compare = [](llvm::StringRef S, Expr Expected) {
+if (auto E = parse(S)) {
+  // Compare both string forms and with operator==, in case we have bugs.
+  EXPECT_EQ(*E, Expected);
+  EXPECT_EQ(sp(*E), sp(Expected));
+} else {
+  handleAllErrors(E.takeError(), [S](const llvm::ErrorInfoBase ) {
+FAIL() << "Failed to parse JSON >>> " << S << " <<<: " << E.message();
+  });
+}
+  };
+
+  Compare(R"(true)", true);
+  Compare(R"(false)", false);
+  Compare(R"(null)", nullptr);
+
+  Compare(R"(42)", 42);
+  Compare(R"(2.5)", 2.5);
+  Compare(R"(2e50)", 2e50);
+  Compare(R"(1.2e3456789)", 1.0 / 0.0);
+
+  Compare(R"("foo")", "foo");
+  Compare(R"("\"\\\b\f\n\r\t")", "\"\\\b\f\n\r\t");
+  Compare(R"("\u")", llvm::StringRef("\0", 1));
+  Compare("\"\x7f\"", "\x7f");
+  Compare(R"("\ud801\udc37")", "\U00010437"); // UTF16 surrogate pair escape.
+  Compare("\"\xE2\x82\xAC\xF0\x9D\x84\x9E\"", "\u20ac\U0001d11e"); // UTF8
+  Compare(R"("\ud801")", "\ufffd"); // Invalid codepoint.
+
+  Compare(R"({"":0,"":0})", obj{{"", 0}});
+  Compare(R"({"obj":{},"arr":[]})", obj{{"obj", obj{}}, {"arr", {}}});
+  Compare(R"({"\n":{"\u":}})",
+  obj{{"\n", obj{
+ {llvm::StringRef("\0", 1), },
+ }}});
+  Compare("\r[\n\t] ", {});
+}
+
+TEST(JSONTest, ParseErrors) {
+  auto ExpectErr = [](llvm::StringRef Msg, llvm::StringRef S) {
+if (auto E = parse(S)) {
+  // Compare both string forms and with operator==, in case we have bugs.
+  FAIL() << "Parsed JSON >>> " << S << " <<< but wanted error: " << Msg;
+} else {
+  handleAllErrors(E.takeError(), [S, Msg](const llvm::ErrorInfoBase ) {
+EXPECT_THAT(E.message(), testing::HasSubstr(Msg)) << S;
+  });
+}
+  };
+  ExpectErr("Unexpected EOF", "");
+  ExpectErr("Unexpected EOF", "[");
+  ExpectErr("Text after end of document", "[][]");
+  ExpectErr("Text after end of document", "[][]");
+  ExpectErr("Invalid bareword", "fuzzy");
+  ExpectErr("Expected , or ]", "[2?]");
+  ExpectErr("Expected object key", "{a:2}");
+  ExpectErr("Expected : after object key", R"({"a",2})");
+  ExpectErr("Expected , or } after object property", R"({"a":2 "b":3})");
+  ExpectErr("Expected JSON value", R"([&%!])");
+  ExpectErr("Invalid number", "1e1.0");
+  ExpectErr("Unterminated string", R"("abc\"def)");
+  ExpectErr("Control character in string", "\"abc\ndef\"");
+  ExpectErr("Invalid escape sequence", R"("\030")");
+  ExpectErr("Invalid \\u escape sequence", R"("\usuck")");
+  ExpectErr("[3:3, byte=19]", R"({
+  "valid": 1,
+  invalid: 2
+})");
+}
+
 } // namespace
 } // namespace json
 } // namespace clangd
Index: unittests/clangd/ClangdTests.cpp
===
--- unittests/clangd/ClangdTests.cpp
+++ unittests/clangd/ClangdTests.cpp
@@ -788,6 +788,8 @@
   int method();
 
   int field;
+private:
+  int private_field;
 };
 
 int test() {
@@ -828,7 +830,10 @@
   // Class members. The only items that must be present in after-dor
   // completion.
   EXPECT_TRUE(ContainsItem(Results, MethodItemText));
+  EXPECT_TRUE(ContainsItem(Results, MethodItemText));
   EXPECT_TRUE(ContainsItem(Results, "field"));
+  EXPECT_EQ(Opts.IncludeIneligibleResults,
+ContainsItem(Results, "private_field"));
   // Global items.
   EXPECT_FALSE(ContainsItem(Results, "global_var"));
   EXPECT_FALSE(ContainsItem(Results, GlobalFuncItemText));
@@ -889,18 +894,26 @@
 }
   };
 
-  for (bool IncludeMacros : {true, false})
-for (bool IncludeGlobals : {true, false})
-  for (bool IncludeBriefComments : {true, false})
-for (bool EnableSnippets : {true, false})
+  clangd::CodeCompleteOptions 

[PATCH] D39836: [clangd] Drop impossible completions (unavailable or inaccessible)

2017-11-09 Thread Sam McCall via Phabricator via cfe-commits
sammccall added a comment.

In https://reviews.llvm.org/D39836#920977, @arphaman wrote:

> In https://reviews.llvm.org/D39836#920587, @sammccall wrote:
>
> > So I probably should have started from the other end, here :-)
> >
> > I'd really like to make the completion retrieval and ranking more flexible. 
> > In particular
> >
> > - incorporating results from other sources (indexes: both in-memory and 
> > external services).
> > - combining more quality signals like usage count and fuzzy-match-strength 
> > in a non-lexicographic-sort way The biggest difficulty in *supporting* 
> > unusable functions is maintaining the invariant that all unusable functions 
> > are ranked lower than usable ones - all code that deals with ranking has to 
> > deal with this special case, e.g. by making score a tuple instead of a 
> > single number.
>
>
> That sounds good to me. Please keep in mind that not all clients might want 
> to take advantage of these things as they might have their own fuzz-match 
> logic


Yup! My understanding of the protocol is clients will generally trigger 
completion after the dot, and then filter client-side *unless* the result set 
is incomplete.
So fuzzy-match filtering/scoring would only be triggered if we limit the number 
of results (proposed as optional in https://reviews.llvm.org/D39852) or if 
completion is explicitly triggered mid-identifier (maybe we should allow 
turning this off too).

> and external result injection.

Absolutely. To be concrete, i'm thinking about three overlaid:

1. a static generated index that clangd consumes (e.g. generated by 
index-while-building and located on disk, or a hosted index of google's 
monorepo)
2. a dynamically generated index of symbols in files that clangd has seen. 
(Likely to be dirty with respect to 1)
3. context-sensitive completion results as today

1 would definitely be optional.
2 isn't really external... we might want to handle global symbols with 2 and 
not 3 as now, but that's an implementation detail.

>> If the current approach of "give them a penalty" is enough, knowing that in 
>> the future it may lead to e.g. a very widely used but inaccessible protected 
>> function being ranked highly, then that seems fine to me too. A wider 
>> configuration space means testing is more work, but happy to live with it. 
>> What do you think?
>> 
>> (With my user-hat on, configurable is fine, though I do strongly feel they 
>> should be off by default, and it seems unlikely many users will change the 
>> defaults.)
> 
> I'd be ok with off by default, as long as it's possible to turn it on :)

Sure, I'll update the patch.

For these things that are (I assume) more "user preference" than project- or 
integration-specific, I wonder whether command-line flags are the right thing. 
Configuration in `~/.clangd` is a can of worms, but might be the right thing in 
the long-run.


https://reviews.llvm.org/D39836



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


[PATCH] D39836: [clangd] Drop impossible completions (unavailable or inaccessible)

2017-11-09 Thread Alex Lorenz via Phabricator via cfe-commits
arphaman added a comment.

In https://reviews.llvm.org/D39836#920587, @sammccall wrote:

> So I probably should have started from the other end, here :-)
>
> I'd really like to make the completion retrieval and ranking more flexible. 
> In particular
>
> - incorporating results from other sources (indexes: both in-memory and 
> external services).
> - combining more quality signals like usage count and fuzzy-match-strength in 
> a non-lexicographic-sort way The biggest difficulty in *supporting* unusable 
> functions is maintaining the invariant that all unusable functions are ranked 
> lower than usable ones - all code that deals with ranking has to deal with 
> this special case, e.g. by making score a tuple instead of a single number.


That sounds good to me. Please keep in mind that not all clients might want to 
take advantage of these things as they might have their own fuzz-match logic 
and external result injection.

> If the current approach of "give them a penalty" is enough, knowing that in 
> the future it may lead to e.g. a very widely used but inaccessible protected 
> function being ranked highly, then that seems fine to me too. A wider 
> configuration space means testing is more work, but happy to live with it. 
> What do you think?
> 
> (With my user-hat on, configurable is fine, though I do strongly feel they 
> should be off by default, and it seems unlikely many users will change the 
> defaults.)

I'd be ok with off by default, as long as it's possible to turn it on :)


https://reviews.llvm.org/D39836



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


[PATCH] D39836: [clangd] Drop impossible completions (unavailable or inaccessible)

2017-11-09 Thread Sam McCall via Phabricator via cfe-commits
sammccall added a comment.

So I probably should have started from the other end, here :-)

I'd really like to make the completion retrieval and ranking more flexible. In 
particular

- incorporating results from other sources (indexes: both in-memory and 
external services).
- combining more quality signals like usage count and fuzzy-match-strength in a 
non-lexicographic-sort way

The biggest difficulty in *supporting* unusable functions is maintaining the 
invariant that all unusable functions are ranked lower than usable ones - all 
code that deals with ranking has to deal with this special case, e.g. by making 
score a tuple instead of a single number.

If the current approach of "give them a penalty" is enough, knowing that in the 
future it may lead to e.g. a very widely used but inaccessible protected 
function being ranked highly, then that seems fine to me too. A wider 
configuration space means testing is more work, but happy to live with it. What 
do you think?

(With my user-hat on, configurable is fine, though I do strongly feel they 
should be off by default, and it seems unlikely many users will change the 
defaults.)


https://reviews.llvm.org/D39836



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


[PATCH] D39836: [clangd] Drop impossible completions (unavailable or inaccessible)

2017-11-09 Thread Alex Lorenz via Phabricator via cfe-commits
arphaman added a comment.

I would prefer to make this behaviour configurable.


https://reviews.llvm.org/D39836



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


[PATCH] D39836: [clangd] Drop impossible completions (unavailable or inaccessible)

2017-11-09 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov accepted this revision.
ilya-biryukov added a comment.
This revision is now accepted and ready to land.

This is probably one of the things that I'd like to be configurable.

In https://reviews.llvm.org/D39836#920313, @sammccall wrote:

> - they bulk up tests and debugging output


I'd argue that the more you put into tests, the more potential errors you'll 
see. E.g. if we're not showing private members, we might miss some presentation 
issues that only those exhibit. And you can always leave them out in tests in 
case you only want to test the public ones (though that's not a good idea, 
probably).
As for debugging, I don't LSP is any good as a debugging format anyway, we 
probably want some different form of output.

> - they complicate the scoring scheme - we *never* want them to appear above a 
> legal completion, so a 1-dimensional score needs special handling as here.

We could always use a 2-dimensional score `(accessible, sort_score)`. I'd love 
to have some editor support to grey-out some items (not only inaccessible, 
deprecated items could have been somehow signalled in completion UI as well), 
probably requires some changes to LSP too and not a priority, though.

> - compute: we spend time scoring them, computing their strings, writing them 
> over the wire, and then the client has to process them

I don't think it matters much, given that there aren't many items that are 
inaccessible compared to the total number of completion items when it's slow 
(they are all class members, but the biggest portion of items come from 
namespaces). And after-dot completion is usually fast (and when it's slow it's 
because reparse is slow, not because we take too much time to process the 
items).

That being said, I don't think there's a chance I'll argue my way through this. 
Let's turn them off and see if someone (besides me) complains. LGTM.


https://reviews.llvm.org/D39836



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


[PATCH] D39836: [clangd] Drop impossible completions (unavailable or inaccessible)

2017-11-09 Thread Manuel Klimek via Phabricator via cfe-commits
klimek added a comment.

In https://reviews.llvm.org/D39836#920313, @sammccall wrote:

> In https://reviews.llvm.org/D39836#920306, @ilya-biryukov wrote:
>
> > I personally think they're useful to have anyway, and they don't add much 
> > noise when they're at the end of completions list.
> >  I sometimes want to complete an item I know is there and then fix 
> > accessibility. Do you think they add too much noise?
>
>
> For me the noise definitely outweighs the value, e.g. when I'm trying to see 
> all the available functions. There are costs beyond noise:
>
> - they bulk up tests and debugging output
> - they complicate the scoring scheme - we *never* want them to appear above a 
> legal completion, so a 1-dimensional score needs special handling as here.
> - compute: we spend time scoring them, computing their strings, writing them 
> over the wire, and then the client has to process them


I do think they are useful to me, but I don't know what the percentages of 
folks who want them vs. not are, and whether people have actually tried 
multiple schemes.
I think it's more likely that we get bug reports to put them in if we don't 
show them than the other way round, so I think taking them out is a good way to 
get that feedback :)


https://reviews.llvm.org/D39836



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


[PATCH] D39836: [clangd] Drop impossible completions (unavailable or inaccessible)

2017-11-09 Thread Sam McCall via Phabricator via cfe-commits
sammccall added a comment.

In https://reviews.llvm.org/D39836#920306, @ilya-biryukov wrote:

> I personally think they're useful to have anyway, and they don't add much 
> noise when they're at the end of completions list.
>  I sometimes want to complete an item I know is there and then fix 
> accessibility. Do you think they add too much noise?


For me the noise definitely outweighs the value, e.g. when I'm trying to see 
all the available functions. There are costs beyond noise:

- they bulk up tests and debugging output
- they complicate the scoring scheme - we *never* want them to appear above a 
legal completion, so a 1-dimensional score needs special handling as here.
- compute: we spend time scoring them, computing their strings, writing them 
over the wire, and then the client has to process them


https://reviews.llvm.org/D39836



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


[PATCH] D39836: [clangd] Drop impossible completions (unavailable or inaccessible)

2017-11-09 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov added a subscriber: klimek.
ilya-biryukov added a comment.

I personally think they're useful to have anyway, and they don't add much noise 
when they're at the end of completions list.
I sometimes want to complete an item I know is there and then fix 
accessibility. Do you think they add too much noise?

I think I'm almost alone in this camp, though. (I remember @klimek saying he 
thinks they're sometimes useful too, but I may be mistaken)


https://reviews.llvm.org/D39836



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


[PATCH] D39836: [clangd] Drop impossible completions (unavailable or inaccessible)

2017-11-09 Thread Sam McCall via Phabricator via cfe-commits
sammccall created this revision.

(There must be some reason why https://reviews.llvm.org/D38077 didn't just do 
this, but I don't get it!)


https://reviews.llvm.org/D39836

Files:
  clangd/ClangdUnit.cpp
  test/clangd/completion-priorities.test
  test/clangd/completion-qualifiers.test

Index: test/clangd/completion-qualifiers.test
===
--- test/clangd/completion-qualifiers.test
+++ test/clangd/completion-qualifiers.test
@@ -11,7 +11,7 @@
 #  CHECK:  "id": 2,
 # CHECK-NEXT:  "jsonrpc": "2.0",
 # CHECK-NEXT:  "result": [
-# Eligible const functions are at the top of the list.
+# Eligible functions are at the top of the list.
 # CHECK-NEXT:{
 # CHECK-NEXT:  "detail": "int",
 # CHECK-NEXT:  "filterText": "bar",
@@ -30,17 +30,9 @@
 # CHECK-NEXT:  "label": "Foo::foo() const",
 # CHECK-NEXT:  "sortText": "37foo"
 # CHECK-NEXT:},
-# Ineligible non-const function is at the bottom of the list.
-# CHECK-NEXT:{
-#  CHECK:  "detail": "int",
-#  CHECK:  "filterText": "foo",
-# CHECK-NEXT:  "insertText": "foo",
-# CHECK-NEXT:  "insertTextFormat": 1,
-# CHECK-NEXT:  "kind": 2,
-# CHECK-NEXT:  "label": "foo() const",
-# CHECK-NEXT:  "sortText": "200035foo"
-# CHECK-NEXT:}
-# CHECK-NEXT:  ]
+# Ineligible private functions are not present.
+#  CHECK-NOT:  "label": "foo() const",
+#  CHECK:  ]
 Content-Length: 44
 
 {"jsonrpc":"2.0","id":4,"method":"shutdown"}
Index: test/clangd/completion-priorities.test
===
--- test/clangd/completion-priorities.test
+++ test/clangd/completion-priorities.test
@@ -57,27 +57,10 @@
 # CHECK-NEXT:  "kind": 2,
 # CHECK-NEXT:  "label": "pub()",
 # CHECK-NEXT:  "sortText": "34pub"
-# CHECK-NEXT:},
-# priv() and prot() are at the end of the list
-# CHECK-NEXT:{
-#  CHECK:  "detail": "void",
-#  CHECK:  "filterText": "priv",
-# CHECK-NEXT:  "insertText": "priv",
-# CHECK-NEXT:  "insertTextFormat": 1,
-# CHECK-NEXT:  "kind": 2,
-# CHECK-NEXT:  "label": "priv()",
-# CHECK-NEXT:  "sortText": "200034priv"
-# CHECK-NEXT:},
-# CHECK-NEXT:{
-# CHECK-NEXT:  "detail": "void",
-# CHECK-NEXT:  "filterText": "prot",
-# CHECK-NEXT:  "insertText": "prot",
-# CHECK-NEXT:  "insertTextFormat": 1,
-# CHECK-NEXT:  "kind": 2,
-# CHECK-NEXT:  "label": "prot()",
-# CHECK-NEXT:  "sortText": "200034prot"
 # CHECK-NEXT:}
-# CHECK-NEXT:  ]
+#  CHECK-NOT:  "label": "priv()",
+#  CHECK-NOT:  "label": "prot()",
+#  CHECK:  ]
 Content-Length: 58
 
 {"jsonrpc":"2.0","id":4,"method":"shutdown","params":null}
Index: clangd/ClangdUnit.cpp
===
--- clangd/ClangdUnit.cpp
+++ clangd/ClangdUnit.cpp
@@ -383,6 +383,9 @@
 Items.reserve(NumResults);
 for (unsigned I = 0; I < NumResults; ++I) {
   auto  = Results[I];
+  if (Result.Availability == CXAvailability_NotAvailable ||
+  Result.Availability == CXAvailability_NotAccessible)
+continue;
   const auto *CCS = Result.CreateCodeCompletionString(
   S, Context, *Allocator, CCTUInfo,
   CodeCompleteOpts.IncludeBriefComments);
@@ -428,23 +431,8 @@
 // Fill in the sortText of the CompletionItem.
 assert(Score <= 9 && "Expecting code completion result "
  "priority to have at most 5-digits");
-
-const int Penalty = 10;
-switch (static_cast(CCS.getAvailability())) {
-case CXAvailability_Available:
-  // No penalty.
-  break;
-case CXAvailability_Deprecated:
-  Score += Penalty;
-  break;
-case CXAvailability_NotAccessible:
-  Score += 2 * Penalty;
-  break;
-case CXAvailability_NotAvailable:
-  Score += 3 * Penalty;
-  break;
-}
-
+if (CCS.getAvailability() == CXAvailability_Deprecated)
+  Score += 10;
 return Score;
   }
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits