From 8b3ebf234b6b1aeaeee8d6d6c5ccc86da51910aa Mon Sep 17 00:00:00 2001
From: Fangrui Song <i@maskray.me>
Date: Fri, 7 Sep 2018 14:38:08 -0700
Subject: [PATCH] Remove $ccls/base and clean up; deduplicate codeLens

---
 CMakeLists.txt                        |  1 -
 src/clang_complete.cc                 | 14 +++---
 src/indexer.cc                        |  1 -
 src/messages/ccls_base.cc             | 66 ---------------------------
 src/messages/ccls_callHierarchy.cc    |  1 -
 src/messages/textDocument_codeLens.cc | 24 +++++-----
 6 files changed, 19 insertions(+), 88 deletions(-)
 delete mode 100644 src/messages/ccls_base.cc

diff --git a/CMakeLists.txt b/CMakeLists.txt
index d48f36b6..9574aad8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -209,7 +209,6 @@ target_sources(ccls PRIVATE
 )
 
 target_sources(ccls PRIVATE
-  src/messages/ccls_base.cc
   src/messages/ccls_callHierarchy.cc
   src/messages/ccls_callers.cc
   src/messages/ccls_fileInfo.cc
diff --git a/src/clang_complete.cc b/src/clang_complete.cc
index 39bc03c8..4d6613af 100644
--- a/src/clang_complete.cc
+++ b/src/clang_complete.cc
@@ -550,7 +550,7 @@ void CompletionPreloadMain(ClangCompleteManager *completion_manager) {
   }
 }
 
-void CompletionQueryMain(ClangCompleteManager *completion_manager) {
+void CompletionMain(ClangCompleteManager *completion_manager) {
   while (true) {
     // Fetching the completion request blocks until we have a request.
     std::unique_ptr<ClangCompleteManager::CompletionRequest> request =
@@ -588,7 +588,7 @@ void CompletionQueryMain(ClangCompleteManager *completion_manager) {
     FOpts.SkipFunctionBodies = true;
     CI->getLangOpts()->CommentOpts.ParseAllComments = true;
 
-    StoreDiags DC;
+    DiagnosticConsumer DC;
     WorkingFiles::Snapshot snapshot =
       completion_manager->working_files_->AsSnapshot({StripFileType(path)});
     std::vector<std::unique_ptr<llvm::MemoryBuffer>> Bufs;
@@ -607,7 +607,7 @@ void CompletionQueryMain(ClangCompleteManager *completion_manager) {
   }
 }
 
-void DiagnosticQueryMain(ClangCompleteManager *manager) {
+void DiagnosticMain(ClangCompleteManager *manager) {
   while (true) {
     // Fetching the completion request blocks until we have a request.
     ClangCompleteManager::DiagnosticRequest request =
@@ -709,8 +709,8 @@ ClangCompleteManager::ClangCompleteManager(Project *project,
       completion_sessions_(kMaxCompletionSessions),
       PCH(std::make_shared<PCHContainerOperations>()) {
   std::thread([&]() {
-    set_thread_name("comp-query");
-    ccls::CompletionQueryMain(this);
+    set_thread_name("comp");
+    ccls::CompletionMain(this);
   })
       .detach();
   std::thread([&]() {
@@ -719,8 +719,8 @@ ClangCompleteManager::ClangCompleteManager(Project *project,
   })
       .detach();
   std::thread([&]() {
-    set_thread_name("diag-query");
-    ccls::DiagnosticQueryMain(this);
+    set_thread_name("diag");
+    ccls::DiagnosticMain(this);
   })
       .detach();
 }
diff --git a/src/indexer.cc b/src/indexer.cc
index ff711a0c..ce53ad16 100644
--- a/src/indexer.cc
+++ b/src/indexer.cc
@@ -1014,7 +1014,6 @@ public:
       break;
     case Decl::EnumConstant:
       var->def.kind = lsSymbolKind::EnumMember;
-      // TODO Pretty printer may print =
       if (is_def && strchr(var->def.detailed_name, '=') == nullptr) {
         auto *ECD = cast<EnumConstantDecl>(D);
         const auto &Val = ECD->getInitVal();
diff --git a/src/messages/ccls_base.cc b/src/messages/ccls_base.cc
deleted file mode 100644
index b5f2b8bb..00000000
--- a/src/messages/ccls_base.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-/* Copyright 2017-2018 ccls Authors
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-==============================================================================*/
-
-#include "message_handler.h"
-#include "pipeline.hh"
-#include "query_utils.h"
-using namespace ccls;
-
-namespace {
-
-MethodType kMethodType = "$ccls/base";
-
-struct In_CclsBase : public RequestInMessage {
-  MethodType GetMethodType() const override { return kMethodType; }
-
-  lsTextDocumentPositionParams params;
-};
-MAKE_REFLECT_STRUCT(In_CclsBase, id, params);
-REGISTER_IN_MESSAGE(In_CclsBase);
-
-struct Handler_CclsBase : BaseMessageHandler<In_CclsBase> {
-  MethodType GetMethodType() const override { return kMethodType; }
-
-  void Run(In_CclsBase *request) override {
-    QueryFile *file;
-    if (!FindFileOrFail(db, project, request->id,
-                        request->params.textDocument.uri.GetPath(), &file)) {
-      return;
-    }
-
-    WorkingFile *working_file =
-        working_files->GetFileByFilename(file->def->path);
-
-    Out_LocationList out;
-    out.id = request->id;
-    for (SymbolRef sym :
-         FindSymbolsAtLocation(working_file, file, request->params.position)) {
-      if (sym.kind == SymbolKind::Type) {
-        if (const auto *def = db->GetType(sym).AnyDef())
-          out.result = GetLsLocationExs(db, working_files,
-                                        GetTypeDeclarations(db, def->bases));
-        break;
-      } else if (sym.kind == SymbolKind::Func) {
-        if (const auto *def = db->GetFunc(sym).AnyDef())
-          out.result = GetLsLocationExs(db, working_files,
-                                        GetFuncDeclarations(db, def->bases));
-        break;
-      }
-    }
-    pipeline::WriteStdout(kMethodType, out);
-  }
-};
-REGISTER_MESSAGE_HANDLER(Handler_CclsBase);
-} // namespace
diff --git a/src/messages/ccls_callHierarchy.cc b/src/messages/ccls_callHierarchy.cc
index 8b139eb4..ce593425 100644
--- a/src/messages/ccls_callHierarchy.cc
+++ b/src/messages/ccls_callHierarchy.cc
@@ -15,7 +15,6 @@ limitations under the License.
 
 #include "message_handler.h"
 #include "pipeline.hh"
-using namespace ccls;
 #include "query_utils.h"
 using namespace ccls;
 
diff --git a/src/messages/textDocument_codeLens.cc b/src/messages/textDocument_codeLens.cc
index 0410c32c..730441e7 100644
--- a/src/messages/textDocument_codeLens.cc
+++ b/src/messages/textDocument_codeLens.cc
@@ -20,19 +20,19 @@ limitations under the License.
 #include "query_utils.h"
 using namespace ccls;
 
+#include <unordered_set>
+
 namespace {
 MethodType kMethodType = "textDocument/codeLens";
 
-struct lsDocumentCodeLensParams {
-  lsTextDocumentIdentifier textDocument;
-};
-MAKE_REFLECT_STRUCT(lsDocumentCodeLensParams, textDocument);
-
 using TCodeLens = lsCodeLens<lsCodeLensUserData, lsCodeLensCommandArguments>;
 struct In_TextDocumentCodeLens : public RequestInMessage {
   MethodType GetMethodType() const override { return kMethodType; }
-  lsDocumentCodeLensParams params;
+  struct Params {
+    lsTextDocumentIdentifier textDocument;
+  } params;
 };
+MAKE_REFLECT_STRUCT(In_TextDocumentCodeLens::Params, textDocument);
 MAKE_REFLECT_STRUCT(In_TextDocumentCodeLens, id, params);
 REGISTER_IN_MESSAGE(In_TextDocumentCodeLens);
 
@@ -96,19 +96,17 @@ struct Handler_TextDocumentCodeLens
     : BaseMessageHandler<In_TextDocumentCodeLens> {
   MethodType GetMethodType() const override { return kMethodType; }
   void Run(In_TextDocumentCodeLens *request) override {
+    auto &params = request->params;
     Out_TextDocumentCodeLens out;
     out.id = request->id;
 
-    lsDocumentUri file_as_uri = request->params.textDocument.uri;
-    std::string path = file_as_uri.GetPath();
-
+    std::string path = params.textDocument.uri.GetPath();
     clang_complete->NotifyView(path);
 
     QueryFile *file;
     if (!FindFileOrFail(db, project, request->id,
-                        request->params.textDocument.uri.GetPath(), &file)) {
+                        params.textDocument.uri.GetPath(), &file))
       return;
-    }
 
     CommonCodeLensParams common;
     common.result = &out.result;
@@ -116,8 +114,10 @@ struct Handler_TextDocumentCodeLens
     common.working_files = working_files;
     common.working_file = working_files->GetFileByFilename(file->def->path);
 
+    std::unordered_set<Range> seen;
     for (auto [sym, refcnt] : file->outline2refcnt) {
-      if (refcnt <= 0) continue;
+      if (refcnt <= 0 || !seen.insert(sym.range).second)
+        continue;
       // NOTE: We OffsetColumn so that the code lens always show up in a
       // predictable order. Otherwise, the client may randomize it.
       Use use{{sym.range, sym.usr, sym.kind, sym.role}, file->id};