mirror of
				https://github.com/MaskRay/ccls.git
				synced 2025-11-04 06:15:20 +00:00 
			
		
		
		
	If clang >= 8, delete search path detection and use Sema::CodeCompleteIncludedFile
This commit is contained in:
		
							parent
							
								
									3e39b86981
								
							
						
					
					
						commit
						cb06324c13
					
				@ -131,13 +131,6 @@ struct PreambleData {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace {
 | 
					namespace {
 | 
				
			||||||
 | 
					 | 
				
			||||||
std::string StripFileType(const std::string &path) {
 | 
					 | 
				
			||||||
  SmallString<128> Ret;
 | 
					 | 
				
			||||||
  sys::path::append(Ret, sys::path::parent_path(path), sys::path::stem(path));
 | 
					 | 
				
			||||||
  return sys::path::convert_to_slash(Ret);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool LocationInRange(SourceLocation L, CharSourceRange R,
 | 
					bool LocationInRange(SourceLocation L, CharSourceRange R,
 | 
				
			||||||
                     const SourceManager &M) {
 | 
					                     const SourceManager &M) {
 | 
				
			||||||
  assert(R.isCharRange());
 | 
					  assert(R.isCharRange());
 | 
				
			||||||
@ -260,23 +253,16 @@ public:
 | 
				
			|||||||
std::unique_ptr<CompilerInstance> BuildCompilerInstance(
 | 
					std::unique_ptr<CompilerInstance> BuildCompilerInstance(
 | 
				
			||||||
    CompletionSession &session, std::unique_ptr<CompilerInvocation> CI,
 | 
					    CompletionSession &session, std::unique_ptr<CompilerInvocation> CI,
 | 
				
			||||||
    IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS, DiagnosticConsumer &DC,
 | 
					    IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS, DiagnosticConsumer &DC,
 | 
				
			||||||
    const PreambleData *preamble, const WorkingFiles::Snapshot &snapshot,
 | 
					    const PreambleData *preamble, const std::string &path,
 | 
				
			||||||
    std::vector<std::unique_ptr<llvm::MemoryBuffer>> &Bufs) {
 | 
					    std::unique_ptr<llvm::MemoryBuffer> &Buf) {
 | 
				
			||||||
  std::string main = ResolveIfRelative(
 | 
					  if (preamble) {
 | 
				
			||||||
      session.file.directory,
 | 
					 | 
				
			||||||
      sys::path::convert_to_slash(CI->getFrontendOpts().Inputs[0].getFile()));
 | 
					 | 
				
			||||||
  for (auto &file : snapshot.files) {
 | 
					 | 
				
			||||||
    Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(file.content));
 | 
					 | 
				
			||||||
    if (preamble && file.filename == main) {
 | 
					 | 
				
			||||||
#if LLVM_VERSION_MAJOR >= 7
 | 
					#if LLVM_VERSION_MAJOR >= 7
 | 
				
			||||||
      preamble->Preamble.OverridePreamble(*CI, FS, Bufs.back().get());
 | 
					    preamble->Preamble.OverridePreamble(*CI, FS, Buf.get());
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
      preamble->Preamble.AddImplicitPreamble(*CI, FS, Bufs.back().get());
 | 
					    preamble->Preamble.AddImplicitPreamble(*CI, FS, Buf.get());
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
      continue;
 | 
					  } else {
 | 
				
			||||||
    }
 | 
					    CI->getPreprocessorOpts().addRemappedFile(path, Buf.get());
 | 
				
			||||||
    CI->getPreprocessorOpts().addRemappedFile(file.filename,
 | 
					 | 
				
			||||||
      Bufs.back().get());
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  auto Clang = std::make_unique<CompilerInstance>(session.PCH);
 | 
					  auto Clang = std::make_unique<CompilerInstance>(session.PCH);
 | 
				
			||||||
@ -347,8 +333,6 @@ void *CompletionPreloadMain(void *manager_) {
 | 
				
			|||||||
      continue;
 | 
					      continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const auto &args = session->file.args;
 | 
					    const auto &args = session->file.args;
 | 
				
			||||||
    WorkingFiles::Snapshot snapshot =
 | 
					 | 
				
			||||||
        session->wfiles->AsSnapshot({StripFileType(session->file.filename)});
 | 
					 | 
				
			||||||
    auto stat_cache = std::make_unique<PreambleStatCache>();
 | 
					    auto stat_cache = std::make_unique<PreambleStatCache>();
 | 
				
			||||||
    IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS =
 | 
					    IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS =
 | 
				
			||||||
        stat_cache->Producer(session->FS);
 | 
					        stat_cache->Producer(session->FS);
 | 
				
			||||||
@ -404,19 +388,24 @@ void *CompletionMain(void *manager_) {
 | 
				
			|||||||
    CI->getLangOpts()->CommentOpts.ParseAllComments = true;
 | 
					    CI->getLangOpts()->CommentOpts.ParseAllComments = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    DiagnosticConsumer DC;
 | 
					    DiagnosticConsumer DC;
 | 
				
			||||||
    WorkingFiles::Snapshot snapshot =
 | 
					    std::string content = manager->wfiles_->GetContent(path);
 | 
				
			||||||
        manager->wfiles_->AsSnapshot({StripFileType(path)});
 | 
					    auto Buf = llvm::MemoryBuffer::getMemBuffer(content);
 | 
				
			||||||
    std::vector<std::unique_ptr<llvm::MemoryBuffer>> Bufs;
 | 
					    bool in_preamble =
 | 
				
			||||||
 | 
					        GetOffsetForPosition(
 | 
				
			||||||
 | 
					            {request->position.line, request->position.character}, content) <
 | 
				
			||||||
 | 
					        ComputePreambleBounds(*CI->getLangOpts(), Buf.get(), 0).Size;
 | 
				
			||||||
 | 
					    if (in_preamble)
 | 
				
			||||||
 | 
					      preamble.reset();
 | 
				
			||||||
    auto Clang = BuildCompilerInstance(*session, std::move(CI), FS, DC,
 | 
					    auto Clang = BuildCompilerInstance(*session, std::move(CI), FS, DC,
 | 
				
			||||||
                                       preamble.get(), snapshot, Bufs);
 | 
					                                       preamble.get(), path, Buf);
 | 
				
			||||||
    if (!Clang)
 | 
					    if (!Clang)
 | 
				
			||||||
      continue;
 | 
					      continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Clang->getPreprocessorOpts().SingleFileParseMode = in_preamble;
 | 
				
			||||||
    Clang->setCodeCompletionConsumer(request->Consumer.release());
 | 
					    Clang->setCodeCompletionConsumer(request->Consumer.release());
 | 
				
			||||||
    if (!Parse(*Clang))
 | 
					    if (!Parse(*Clang))
 | 
				
			||||||
      continue;
 | 
					      continue;
 | 
				
			||||||
    for (auto &Buf : Bufs)
 | 
					    Buf.release();
 | 
				
			||||||
      Buf.release();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    request->on_complete(&Clang->getCodeCompletionConsumer());
 | 
					    request->on_complete(&Clang->getCodeCompletionConsumer());
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -471,6 +460,7 @@ void *DiagnosticMain(void *manager_) {
 | 
				
			|||||||
    std::shared_ptr<PreambleData> preamble = session->GetPreamble();
 | 
					    std::shared_ptr<PreambleData> preamble = session->GetPreamble();
 | 
				
			||||||
    IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS =
 | 
					    IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS =
 | 
				
			||||||
        preamble ? preamble->stat_cache->Consumer(session->FS) : session->FS;
 | 
					        preamble ? preamble->stat_cache->Consumer(session->FS) : session->FS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::unique_ptr<CompilerInvocation> CI =
 | 
					    std::unique_ptr<CompilerInvocation> CI =
 | 
				
			||||||
        BuildCompilerInvocation(session->file.args, FS);
 | 
					        BuildCompilerInvocation(session->file.args, FS);
 | 
				
			||||||
    if (!CI)
 | 
					    if (!CI)
 | 
				
			||||||
@ -478,17 +468,15 @@ void *DiagnosticMain(void *manager_) {
 | 
				
			|||||||
    CI->getDiagnosticOpts().IgnoreWarnings = false;
 | 
					    CI->getDiagnosticOpts().IgnoreWarnings = false;
 | 
				
			||||||
    CI->getLangOpts()->SpellChecking = g_config->diagnostics.spellChecking;
 | 
					    CI->getLangOpts()->SpellChecking = g_config->diagnostics.spellChecking;
 | 
				
			||||||
    StoreDiags DC(path);
 | 
					    StoreDiags DC(path);
 | 
				
			||||||
    WorkingFiles::Snapshot snapshot =
 | 
					    std::string content = manager->wfiles_->GetContent(path);
 | 
				
			||||||
        manager->wfiles_->AsSnapshot({StripFileType(path)});
 | 
					    auto Buf = llvm::MemoryBuffer::getMemBuffer(content);
 | 
				
			||||||
    std::vector<std::unique_ptr<llvm::MemoryBuffer>> Bufs;
 | 
					 | 
				
			||||||
    auto Clang = BuildCompilerInstance(*session, std::move(CI), FS, DC,
 | 
					    auto Clang = BuildCompilerInstance(*session, std::move(CI), FS, DC,
 | 
				
			||||||
                                       preamble.get(), snapshot, Bufs);
 | 
					                                       preamble.get(), path, Buf);
 | 
				
			||||||
    if (!Clang)
 | 
					    if (!Clang)
 | 
				
			||||||
      continue;
 | 
					      continue;
 | 
				
			||||||
    if (!Parse(*Clang))
 | 
					    if (!Parse(*Clang))
 | 
				
			||||||
      continue;
 | 
					      continue;
 | 
				
			||||||
    for (auto &Buf : Bufs)
 | 
					    Buf.release();
 | 
				
			||||||
      Buf.release();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto Fill = [](const DiagBase &d, Diagnostic &ret) {
 | 
					    auto Fill = [](const DiagBase &d, Diagnostic &ret) {
 | 
				
			||||||
      ret.range = lsRange{{d.range.start.line, d.range.start.column},
 | 
					      ret.range = lsRange{{d.range.start.line, d.range.start.column},
 | 
				
			||||||
 | 
				
			|||||||
@ -92,7 +92,7 @@ IncludeComplete::IncludeComplete(Project *project)
 | 
				
			|||||||
    : is_scanning(false), project_(project) {}
 | 
					    : is_scanning(false), project_(project) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void IncludeComplete::Rescan() {
 | 
					void IncludeComplete::Rescan() {
 | 
				
			||||||
  if (is_scanning)
 | 
					  if (is_scanning || LLVM_VERSION_MAJOR >= 8)
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  completion_items.clear();
 | 
					  completion_items.clear();
 | 
				
			||||||
 | 
				
			|||||||
@ -12,7 +12,9 @@
 | 
				
			|||||||
#include <clang/Sema/CodeCompleteConsumer.h>
 | 
					#include <clang/Sema/CodeCompleteConsumer.h>
 | 
				
			||||||
#include <clang/Sema/Sema.h>
 | 
					#include <clang/Sema/Sema.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if LLVM_VERSION_MAJOR < 8
 | 
				
			||||||
#include <regex>
 | 
					#include <regex>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace ccls {
 | 
					namespace ccls {
 | 
				
			||||||
using namespace clang;
 | 
					using namespace clang;
 | 
				
			||||||
@ -31,6 +33,7 @@ struct CompletionList {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
MAKE_REFLECT_STRUCT(CompletionList, isIncomplete, items);
 | 
					MAKE_REFLECT_STRUCT(CompletionList, isIncomplete, items);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if LLVM_VERSION_MAJOR < 8
 | 
				
			||||||
void DecorateIncludePaths(const std::smatch &match,
 | 
					void DecorateIncludePaths(const std::smatch &match,
 | 
				
			||||||
                          std::vector<CompletionItem> *items) {
 | 
					                          std::vector<CompletionItem> *items) {
 | 
				
			||||||
  std::string spaces_after_include = " ";
 | 
					  std::string spaces_after_include = " ";
 | 
				
			||||||
@ -78,6 +81,7 @@ ParseIncludeLineResult ParseIncludeLine(const std::string &line) {
 | 
				
			|||||||
  bool ok = std::regex_match(line, match, pattern);
 | 
					  bool ok = std::regex_match(line, match, pattern);
 | 
				
			||||||
  return {ok, match[3], match[5], match[6], match};
 | 
					  return {ok, match[3], match[5], match[6], match};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Pre-filters completion responses before sending to vscode. This results in a
 | 
					// Pre-filters completion responses before sending to vscode. This results in a
 | 
				
			||||||
// significantly snappier completion experience as vscode is easily overloaded
 | 
					// significantly snappier completion experience as vscode is easily overloaded
 | 
				
			||||||
@ -109,7 +113,7 @@ void FilterCandidates(CompletionList &result, const std::string &complete_text,
 | 
				
			|||||||
    for (auto &item : items) {
 | 
					    for (auto &item : items) {
 | 
				
			||||||
      item.textEdit.range = lsRange{begin_pos, end_pos};
 | 
					      item.textEdit.range = lsRange{begin_pos, end_pos};
 | 
				
			||||||
      if (has_open_paren && item.filterText)
 | 
					      if (has_open_paren && item.filterText)
 | 
				
			||||||
        item.textEdit.newText = item.filterText.value();
 | 
					        item.textEdit.newText = *item.filterText;
 | 
				
			||||||
      // https://github.com/Microsoft/language-server-protocol/issues/543
 | 
					      // https://github.com/Microsoft/language-server-protocol/issues/543
 | 
				
			||||||
      // Order of textEdit and additionalTextEdits is unspecified.
 | 
					      // Order of textEdit and additionalTextEdits is unspecified.
 | 
				
			||||||
      auto &edits = item.additionalTextEdits;
 | 
					      auto &edits = item.additionalTextEdits;
 | 
				
			||||||
@ -121,7 +125,7 @@ void FilterCandidates(CompletionList &result, const std::string &complete_text,
 | 
				
			|||||||
          item.filterText =
 | 
					          item.filterText =
 | 
				
			||||||
              buffer_line.substr(start.character,
 | 
					              buffer_line.substr(start.character,
 | 
				
			||||||
                                 end.character - start.character) +
 | 
					                                 end.character - start.character) +
 | 
				
			||||||
              item.filterText.value();
 | 
					              *item.filterText;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        edits.erase(edits.begin());
 | 
					        edits.erase(edits.begin());
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@ -379,6 +383,10 @@ public:
 | 
				
			|||||||
          includeBriefComments());
 | 
					          includeBriefComments());
 | 
				
			||||||
      CompletionItem ls_item;
 | 
					      CompletionItem ls_item;
 | 
				
			||||||
      ls_item.kind = GetCompletionKind(R.CursorKind);
 | 
					      ls_item.kind = GetCompletionKind(R.CursorKind);
 | 
				
			||||||
 | 
					#if LLVM_VERSION_MAJOR >= 8
 | 
				
			||||||
 | 
					      if (Context.getKind() == CodeCompletionContext::CCC_IncludedFile)
 | 
				
			||||||
 | 
					        ls_item.kind = CompletionItemKind::File;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
      if (const char *brief = CCS->getBriefComment())
 | 
					      if (const char *brief = CCS->getBriefComment())
 | 
				
			||||||
        ls_item.documentation = brief;
 | 
					        ls_item.documentation = brief;
 | 
				
			||||||
      ls_item.detail = CCS->getParentContextName().str();
 | 
					      ls_item.detail = CCS->getParentContextName().str();
 | 
				
			||||||
@ -431,51 +439,44 @@ void MessageHandler::textDocument_completion(CompletionParam ¶m,
 | 
				
			|||||||
      param.position.line < file->buffer_lines.size())
 | 
					      param.position.line < file->buffer_lines.size())
 | 
				
			||||||
    buffer_line = file->buffer_lines[param.position.line];
 | 
					    buffer_line = file->buffer_lines[param.position.line];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Check for - and : before completing -> or ::, since vscode does not
 | 
					  clang::CodeCompleteOptions CCOpts;
 | 
				
			||||||
  // support multi-character trigger characters.
 | 
					  CCOpts.IncludeBriefComments = true;
 | 
				
			||||||
 | 
					  CCOpts.IncludeCodePatterns = StringRef(buffer_line).ltrim().startswith("#");
 | 
				
			||||||
 | 
					#if LLVM_VERSION_MAJOR >= 7
 | 
				
			||||||
 | 
					  CCOpts.IncludeFixIts = true;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					  CCOpts.IncludeMacros = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (param.context.triggerKind == CompletionTriggerKind::TriggerCharacter &&
 | 
					  if (param.context.triggerKind == CompletionTriggerKind::TriggerCharacter &&
 | 
				
			||||||
      param.context.triggerCharacter) {
 | 
					      param.context.triggerCharacter) {
 | 
				
			||||||
    bool did_fail_check = false;
 | 
					    bool ok = true;
 | 
				
			||||||
 | 
					    int col = param.position.character - 2;
 | 
				
			||||||
    std::string character = *param.context.triggerCharacter;
 | 
					    switch ((*param.context.triggerCharacter)[0]) {
 | 
				
			||||||
    int preceding_index = param.position.character - 2;
 | 
					    case '"':
 | 
				
			||||||
 | 
					    case '/':
 | 
				
			||||||
    // If the character is '"', '<' or '/', make sure that the line starts
 | 
					    case '<':
 | 
				
			||||||
    // with '#'.
 | 
					      ok = CCOpts.IncludeCodePatterns; // start with #
 | 
				
			||||||
    if (character == "\"" || character == "<" || character == "/") {
 | 
					      break;
 | 
				
			||||||
      size_t i = 0;
 | 
					    case ':':
 | 
				
			||||||
      while (i < buffer_line.size() && isspace(buffer_line[i]))
 | 
					      ok = col >= 0 && buffer_line[col] == ':'; // ::
 | 
				
			||||||
        ++i;
 | 
					      break;
 | 
				
			||||||
      if (i >= buffer_line.size() || buffer_line[i] != '#')
 | 
					    case '>':
 | 
				
			||||||
        did_fail_check = true;
 | 
					      ok = col >= 0 && buffer_line[col] == '-'; // ->
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    // If the character is > or : and we are at the start of the line, do not
 | 
					    if (!ok) {
 | 
				
			||||||
    // show completion results.
 | 
					 | 
				
			||||||
    else if ((character == ">" || character == ":") && preceding_index < 0) {
 | 
					 | 
				
			||||||
      did_fail_check = true;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    // If the character is > but - does not preced it, or if it is : and :
 | 
					 | 
				
			||||||
    // does not preced it, do not show completion results.
 | 
					 | 
				
			||||||
    else if (preceding_index >= 0 &&
 | 
					 | 
				
			||||||
             preceding_index < (int)buffer_line.size()) {
 | 
					 | 
				
			||||||
      char preceding = buffer_line[preceding_index];
 | 
					 | 
				
			||||||
      did_fail_check = (preceding != '-' && character == ">") ||
 | 
					 | 
				
			||||||
                       (preceding != ':' && character == ":");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (did_fail_check) {
 | 
					 | 
				
			||||||
      reply(result);
 | 
					      reply(result);
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  std::string completion_text;
 | 
					  std::string filter;
 | 
				
			||||||
  Position end_pos = param.position;
 | 
					  Position end_pos = param.position;
 | 
				
			||||||
  Position begin_pos = file->FindStableCompletionSource(
 | 
					  Position begin_pos =
 | 
				
			||||||
      param.position, &completion_text, &end_pos);
 | 
					      file->FindStableCompletionSource(param.position, &filter, &end_pos);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if LLVM_VERSION_MAJOR < 8
 | 
				
			||||||
  ParseIncludeLineResult preprocess = ParseIncludeLine(buffer_line);
 | 
					  ParseIncludeLineResult preprocess = ParseIncludeLine(buffer_line);
 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (preprocess.ok && preprocess.keyword.compare("include") == 0) {
 | 
					  if (preprocess.ok && preprocess.keyword.compare("include") == 0) {
 | 
				
			||||||
    CompletionList result;
 | 
					    CompletionList result;
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -494,47 +495,40 @@ void MessageHandler::textDocument_completion(CompletionParam ¶m,
 | 
				
			|||||||
                     buffer_line);
 | 
					                     buffer_line);
 | 
				
			||||||
    DecorateIncludePaths(preprocess.match, &result.items);
 | 
					    DecorateIncludePaths(preprocess.match, &result.items);
 | 
				
			||||||
    reply(result);
 | 
					    reply(result);
 | 
				
			||||||
  } else {
 | 
					    return;
 | 
				
			||||||
    std::string path = param.textDocument.uri.GetPath();
 | 
					  }
 | 
				
			||||||
    CompletionManager::OnComplete callback =
 | 
					 | 
				
			||||||
        [completion_text, path, begin_pos, end_pos, reply,
 | 
					 | 
				
			||||||
         buffer_line](CodeCompleteConsumer *OptConsumer) {
 | 
					 | 
				
			||||||
          if (!OptConsumer)
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
          auto *Consumer = static_cast<CompletionConsumer *>(OptConsumer);
 | 
					 | 
				
			||||||
          CompletionList result;
 | 
					 | 
				
			||||||
          result.items = Consumer->ls_items;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          FilterCandidates(result, completion_text, begin_pos, end_pos,
 | 
					 | 
				
			||||||
                           buffer_line);
 | 
					 | 
				
			||||||
          reply(result);
 | 
					 | 
				
			||||||
          if (!Consumer->from_cache) {
 | 
					 | 
				
			||||||
            cache.WithLock([&]() {
 | 
					 | 
				
			||||||
              cache.path = path;
 | 
					 | 
				
			||||||
              cache.position = begin_pos;
 | 
					 | 
				
			||||||
              cache.result = Consumer->ls_items;
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    clang::CodeCompleteOptions CCOpts;
 | 
					 | 
				
			||||||
    CCOpts.IncludeBriefComments = true;
 | 
					 | 
				
			||||||
    CCOpts.IncludeCodePatterns = preprocess.ok; // if there is a #
 | 
					 | 
				
			||||||
#if LLVM_VERSION_MAJOR >= 7
 | 
					 | 
				
			||||||
    CCOpts.IncludeFixIts = true;
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    CCOpts.IncludeMacros = true;
 | 
					
 | 
				
			||||||
    if (cache.IsCacheValid(path, begin_pos)) {
 | 
					  CompletionManager::OnComplete callback =
 | 
				
			||||||
      CompletionConsumer Consumer(CCOpts, true);
 | 
					      [filter, path, begin_pos, end_pos, reply,
 | 
				
			||||||
      cache.WithLock([&]() { Consumer.ls_items = cache.result; });
 | 
					       buffer_line](CodeCompleteConsumer *OptConsumer) {
 | 
				
			||||||
      callback(&Consumer);
 | 
					        if (!OptConsumer)
 | 
				
			||||||
    } else {
 | 
					          return;
 | 
				
			||||||
      clang_complete->completion_request_.PushBack(
 | 
					        auto *Consumer = static_cast<CompletionConsumer *>(OptConsumer);
 | 
				
			||||||
          std::make_unique<CompletionManager::CompletionRequest>(
 | 
					        CompletionList result;
 | 
				
			||||||
              reply.id, param.textDocument, begin_pos,
 | 
					        result.items = Consumer->ls_items;
 | 
				
			||||||
              std::make_unique<CompletionConsumer>(CCOpts, false), CCOpts,
 | 
					
 | 
				
			||||||
              callback));
 | 
					        FilterCandidates(result, filter, begin_pos, end_pos, buffer_line);
 | 
				
			||||||
    }
 | 
					        reply(result);
 | 
				
			||||||
 | 
					        if (!Consumer->from_cache) {
 | 
				
			||||||
 | 
					          cache.WithLock([&]() {
 | 
				
			||||||
 | 
					            cache.path = path;
 | 
				
			||||||
 | 
					            cache.position = begin_pos;
 | 
				
			||||||
 | 
					            cache.result = Consumer->ls_items;
 | 
				
			||||||
 | 
					          });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (cache.IsCacheValid(path, begin_pos)) {
 | 
				
			||||||
 | 
					    CompletionConsumer Consumer(CCOpts, true);
 | 
				
			||||||
 | 
					    cache.WithLock([&]() { Consumer.ls_items = cache.result; });
 | 
				
			||||||
 | 
					    callback(&Consumer);
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    clang_complete->completion_request_.PushBack(
 | 
				
			||||||
 | 
					        std::make_unique<CompletionManager::CompletionRequest>(
 | 
				
			||||||
 | 
					            reply.id, param.textDocument, begin_pos,
 | 
				
			||||||
 | 
					            std::make_unique<CompletionConsumer>(CCOpts, false), CCOpts,
 | 
				
			||||||
 | 
					            callback));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
} // namespace ccls
 | 
					} // namespace ccls
 | 
				
			||||||
 | 
				
			|||||||
@ -129,6 +129,7 @@ struct ProjectProcessor {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    args.push_back(Intern("-working-directory=" + entry.directory));
 | 
					    args.push_back(Intern("-working-directory=" + entry.directory));
 | 
				
			||||||
    entry.args = args;
 | 
					    entry.args = args;
 | 
				
			||||||
 | 
					#if LLVM_VERSION_MAJOR < 8
 | 
				
			||||||
    args.push_back("-fsyntax-only");
 | 
					    args.push_back("-fsyntax-only");
 | 
				
			||||||
    if (!command_set.insert(hash).second)
 | 
					    if (!command_set.insert(hash).second)
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
@ -179,6 +180,7 @@ struct ProjectProcessor {
 | 
				
			|||||||
        break;
 | 
					        break;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user