mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-26 17:41:58 +00:00
Remove ASTUnit from indexer and clean up
This commit is contained in:
parent
5cc3006a3a
commit
407c7cc29d
@ -1,10 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
OUTPUT:
|
OUTPUT:
|
||||||
{
|
{}
|
||||||
"includes": [],
|
|
||||||
"skipped_ranges": [],
|
|
||||||
"usr2func": [],
|
|
||||||
"usr2type": [],
|
|
||||||
"usr2var": []
|
|
||||||
}
|
|
||||||
*/
|
*/
|
||||||
|
@ -21,7 +21,6 @@ limitations under the License.
|
|||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
|
|
||||||
#include <clang/Frontend/CompilerInstance.h>
|
#include <clang/Frontend/CompilerInstance.h>
|
||||||
#include <clang/Frontend/FrontendDiagnostic.h>
|
|
||||||
#include <clang/Lex/PreprocessorOptions.h>
|
#include <clang/Lex/PreprocessorOptions.h>
|
||||||
#include <clang/Sema/CodeCompleteConsumer.h>
|
#include <clang/Sema/CodeCompleteConsumer.h>
|
||||||
#include <llvm/ADT/Twine.h>
|
#include <llvm/ADT/Twine.h>
|
||||||
@ -397,10 +396,6 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
|
|
||||||
OverloadCandidate *Candidates,
|
|
||||||
unsigned NumCandidates) override {}
|
|
||||||
|
|
||||||
CodeCompletionAllocator &getAllocator() override { return *Alloc; }
|
CodeCompletionAllocator &getAllocator() override { return *Alloc; }
|
||||||
|
|
||||||
CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo; }
|
CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo; }
|
||||||
@ -484,30 +479,10 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<CompilerInvocation>
|
std::unique_ptr<CompilerInstance> BuildCompilerInstance(
|
||||||
buildCompilerInvocation(const std::vector<std::string> &args,
|
CompletionSession &session, std::unique_ptr<CompilerInvocation> CI,
|
||||||
IntrusiveRefCntPtr<vfs::FileSystem> VFS) {
|
DiagnosticConsumer &DC, const WorkingFiles::Snapshot &snapshot,
|
||||||
std::vector<const char *> cargs;
|
std::vector<std::unique_ptr<llvm::MemoryBuffer>> &Bufs) {
|
||||||
for (auto &arg : args)
|
|
||||||
cargs.push_back(arg.c_str());
|
|
||||||
IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
|
|
||||||
CompilerInstance::createDiagnostics(new DiagnosticOptions));
|
|
||||||
std::unique_ptr<CompilerInvocation> CI =
|
|
||||||
createInvocationFromCommandLine(cargs, Diags, VFS);
|
|
||||||
if (CI) {
|
|
||||||
CI->getFrontendOpts().DisableFree = false;
|
|
||||||
CI->getLangOpts()->CommentOpts.ParseAllComments = true;
|
|
||||||
CI->getLangOpts()->SpellChecking = false;
|
|
||||||
}
|
|
||||||
return CI;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<CompilerInstance>
|
|
||||||
BuildCompilerInstance(CompletionSession &session,
|
|
||||||
std::unique_ptr<CompilerInvocation> CI,
|
|
||||||
DiagnosticConsumer &DC,
|
|
||||||
const WorkingFiles::Snapshot &snapshot,
|
|
||||||
std::vector<std::unique_ptr<llvm::MemoryBuffer>> &Bufs) {
|
|
||||||
for (auto &file : snapshot.files) {
|
for (auto &file : snapshot.files) {
|
||||||
Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(file.content));
|
Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(file.content));
|
||||||
if (file.filename == session.file.filename) {
|
if (file.filename == session.file.filename) {
|
||||||
@ -570,7 +545,7 @@ void CompletionPreloadMain(ClangCompleteManager *completion_manager) {
|
|||||||
|
|
||||||
LOG_S(INFO) << "create completion session for " << session->file.filename;
|
LOG_S(INFO) << "create completion session for " << session->file.filename;
|
||||||
if (std::unique_ptr<CompilerInvocation> CI =
|
if (std::unique_ptr<CompilerInvocation> CI =
|
||||||
buildCompilerInvocation(args, session->FS))
|
BuildCompilerInvocation(args, session->FS))
|
||||||
session->BuildPreamble(*CI);
|
session->BuildPreamble(*CI);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -595,10 +570,12 @@ void CompletionQueryMain(ClangCompleteManager *completion_manager) {
|
|||||||
true /*create_if_needed*/);
|
true /*create_if_needed*/);
|
||||||
|
|
||||||
std::unique_ptr<CompilerInvocation> CI =
|
std::unique_ptr<CompilerInvocation> CI =
|
||||||
buildCompilerInvocation(session->file.args, session->FS);
|
BuildCompilerInvocation(session->file.args, session->FS);
|
||||||
if (!CI)
|
if (!CI)
|
||||||
continue;
|
continue;
|
||||||
|
CI->getDiagnosticOpts().IgnoreWarnings = true;
|
||||||
clang::CodeCompleteOptions CCOpts;
|
clang::CodeCompleteOptions CCOpts;
|
||||||
|
CCOpts.IncludeBriefComments = true;
|
||||||
#if LLVM_VERSION_MAJOR >= 7
|
#if LLVM_VERSION_MAJOR >= 7
|
||||||
CCOpts.IncludeFixIts = true;
|
CCOpts.IncludeFixIts = true;
|
||||||
#endif
|
#endif
|
||||||
@ -608,6 +585,8 @@ void CompletionQueryMain(ClangCompleteManager *completion_manager) {
|
|||||||
FOpts.CodeCompletionAt.FileName = session->file.filename;
|
FOpts.CodeCompletionAt.FileName = session->file.filename;
|
||||||
FOpts.CodeCompletionAt.Line = request->position.line + 1;
|
FOpts.CodeCompletionAt.Line = request->position.line + 1;
|
||||||
FOpts.CodeCompletionAt.Column = request->position.character + 1;
|
FOpts.CodeCompletionAt.Column = request->position.character + 1;
|
||||||
|
FOpts.SkipFunctionBodies = true;
|
||||||
|
CI->getLangOpts()->CommentOpts.ParseAllComments = true;
|
||||||
|
|
||||||
StoreDiags DC;
|
StoreDiags DC;
|
||||||
WorkingFiles::Snapshot snapshot =
|
WorkingFiles::Snapshot snapshot =
|
||||||
@ -641,7 +620,7 @@ void DiagnosticQueryMain(ClangCompleteManager *manager) {
|
|||||||
path, true /*mark_as_completion*/, true /*create_if_needed*/);
|
path, true /*mark_as_completion*/, true /*create_if_needed*/);
|
||||||
|
|
||||||
std::unique_ptr<CompilerInvocation> CI =
|
std::unique_ptr<CompilerInvocation> CI =
|
||||||
buildCompilerInvocation(session->file.args, session->FS);
|
BuildCompilerInvocation(session->file.args, session->FS);
|
||||||
if (!CI)
|
if (!CI)
|
||||||
continue;
|
continue;
|
||||||
StoreDiags DC;
|
StoreDiags DC;
|
||||||
@ -701,6 +680,7 @@ void CompletionSession::BuildPreamble(CompilerInvocation &CI) {
|
|||||||
if (OldP && OldP->Preamble.CanReuse(CI, Buf.get(), Bounds, FS.get()))
|
if (OldP && OldP->Preamble.CanReuse(CI, Buf.get(), Bounds, FS.get()))
|
||||||
return;
|
return;
|
||||||
CI.getFrontendOpts().SkipFunctionBodies = true;
|
CI.getFrontendOpts().SkipFunctionBodies = true;
|
||||||
|
CI.getLangOpts()->CommentOpts.ParseAllComments = true;
|
||||||
#if LLVM_VERSION_MAJOR >= 7
|
#if LLVM_VERSION_MAJOR >= 7
|
||||||
CI.getPreprocessorOpts().WriteCommentListToPCH = false;
|
CI.getPreprocessorOpts().WriteCommentListToPCH = false;
|
||||||
#endif
|
#endif
|
||||||
|
@ -63,3 +63,20 @@ Range FromTokenRange(const SourceManager &SM, const LangOptions &LangOpts,
|
|||||||
return FromCharSourceRange(SM, LangOpts, CharSourceRange::getTokenRange(R),
|
return FromCharSourceRange(SM, LangOpts, CharSourceRange::getTokenRange(R),
|
||||||
UniqueID);
|
UniqueID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<CompilerInvocation>
|
||||||
|
BuildCompilerInvocation(const std::vector<std::string> &args,
|
||||||
|
IntrusiveRefCntPtr<vfs::FileSystem> VFS) {
|
||||||
|
std::vector<const char *> cargs;
|
||||||
|
for (auto &arg : args)
|
||||||
|
cargs.push_back(arg.c_str());
|
||||||
|
IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
|
||||||
|
CompilerInstance::createDiagnostics(new DiagnosticOptions));
|
||||||
|
std::unique_ptr<CompilerInvocation> CI =
|
||||||
|
createInvocationFromCommandLine(cargs, Diags, VFS);
|
||||||
|
if (CI) {
|
||||||
|
CI->getFrontendOpts().DisableFree = false;
|
||||||
|
CI->getLangOpts()->SpellChecking = false;
|
||||||
|
}
|
||||||
|
return CI;
|
||||||
|
}
|
||||||
|
@ -18,6 +18,7 @@ limitations under the License.
|
|||||||
|
|
||||||
#include <clang/Basic/LangOptions.h>
|
#include <clang/Basic/LangOptions.h>
|
||||||
#include <clang/Basic/SourceManager.h>
|
#include <clang/Basic/SourceManager.h>
|
||||||
|
#include <clang/Frontend/CompilerInstance.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
@ -33,3 +34,7 @@ Range FromCharRange(const clang::SourceManager &SM,
|
|||||||
Range FromTokenRange(const clang::SourceManager &SM,
|
Range FromTokenRange(const clang::SourceManager &SM,
|
||||||
const clang::LangOptions &LangOpts, clang::SourceRange R,
|
const clang::LangOptions &LangOpts, clang::SourceRange R,
|
||||||
llvm::sys::fs::UniqueID *UniqueID = nullptr);
|
llvm::sys::fs::UniqueID *UniqueID = nullptr);
|
||||||
|
|
||||||
|
std::unique_ptr<clang::CompilerInvocation>
|
||||||
|
BuildCompilerInvocation(const std::vector<std::string> &args,
|
||||||
|
llvm::IntrusiveRefCntPtr<clang::vfs::FileSystem> VFS);
|
||||||
|
@ -22,8 +22,6 @@ limitations under the License.
|
|||||||
using ccls::Intern;
|
using ccls::Intern;
|
||||||
|
|
||||||
#include <clang/AST/AST.h>
|
#include <clang/AST/AST.h>
|
||||||
#include <clang/Frontend/ASTUnit.h>
|
|
||||||
#include <clang/Frontend/CompilerInstance.h>
|
|
||||||
#include <clang/Frontend/FrontendAction.h>
|
#include <clang/Frontend/FrontendAction.h>
|
||||||
#include <clang/Index/IndexDataConsumer.h>
|
#include <clang/Index/IndexDataConsumer.h>
|
||||||
#include <clang/Index/IndexingAction.h>
|
#include <clang/Index/IndexingAction.h>
|
||||||
@ -57,13 +55,10 @@ struct IndexParam {
|
|||||||
};
|
};
|
||||||
std::unordered_map<const Decl *, DeclInfo> Decl2Info;
|
std::unordered_map<const Decl *, DeclInfo> Decl2Info;
|
||||||
|
|
||||||
ASTUnit &Unit;
|
|
||||||
ASTContext *Ctx;
|
ASTContext *Ctx;
|
||||||
|
|
||||||
FileConsumer *file_consumer = nullptr;
|
FileConsumer *file_consumer = nullptr;
|
||||||
|
|
||||||
IndexParam(ASTUnit &Unit, FileConsumer *file_consumer)
|
IndexParam(FileConsumer *file_consumer) : file_consumer(file_consumer) {}
|
||||||
: Unit(Unit), file_consumer(file_consumer) {}
|
|
||||||
|
|
||||||
IndexFile *ConsumeFile(const FileEntry &File) {
|
IndexFile *ConsumeFile(const FileEntry &File) {
|
||||||
IndexFile *db = file_consumer->TryConsumeFile(File, &file_contents);
|
IndexFile *db = file_consumer->TryConsumeFile(File, &file_contents);
|
||||||
@ -1173,21 +1168,15 @@ Index(VFS *vfs, const std::string &opt_wdir, const std::string &file,
|
|||||||
if (!g_config->index.enabled)
|
if (!g_config->index.enabled)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
std::vector<const char *> Args;
|
auto PCH = std::make_shared<PCHContainerOperations>();
|
||||||
for (auto &arg : args)
|
llvm::IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getRealFileSystem();
|
||||||
Args.push_back(arg.c_str());
|
std::shared_ptr<CompilerInvocation> CI = BuildCompilerInvocation(args, FS);
|
||||||
auto PCHCO = std::make_shared<PCHContainerOperations>();
|
|
||||||
IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
|
|
||||||
CompilerInstance::createDiagnostics(new DiagnosticOptions));
|
|
||||||
std::shared_ptr<CompilerInvocation> CI =
|
|
||||||
createInvocationFromCommandLine(Args, Diags);
|
|
||||||
if (!CI)
|
if (!CI)
|
||||||
return {};
|
return {};
|
||||||
// -fparse-all-comments enables documentation in the indexer and in
|
// -fparse-all-comments enables documentation in the indexer and in
|
||||||
// code completion.
|
// code completion.
|
||||||
if (g_config->index.comments > 1)
|
if (g_config->index.comments > 1)
|
||||||
CI->getLangOpts()->CommentOpts.ParseAllComments = true;
|
CI->getLangOpts()->CommentOpts.ParseAllComments = true;
|
||||||
CI->getLangOpts()->SpellChecking = false;
|
|
||||||
{
|
{
|
||||||
// FileSystemOptions& FSOpts = CI->getFileSystemOpts();
|
// FileSystemOptions& FSOpts = CI->getFileSystemOpts();
|
||||||
// if (FSOpts.WorkingDir.empty())
|
// if (FSOpts.WorkingDir.empty())
|
||||||
@ -1200,20 +1189,18 @@ Index(VFS *vfs, const std::string &opt_wdir, const std::string &file,
|
|||||||
// HSOpts.ResourceDir = g_config->clang.resourceDir;
|
// HSOpts.ResourceDir = g_config->clang.resourceDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::unique_ptr<llvm::MemoryBuffer>> BufOwner;
|
DiagnosticConsumer DC;
|
||||||
for (auto &c : file_contents) {
|
auto Clang = std::make_unique<CompilerInstance>(PCH);
|
||||||
std::unique_ptr<llvm::MemoryBuffer> MB =
|
Clang->setInvocation(std::move(CI));
|
||||||
llvm::MemoryBuffer::getMemBufferCopy(c.content, c.path);
|
Clang->setVirtualFileSystem(FS);
|
||||||
CI->getPreprocessorOpts().addRemappedFile(c.path, MB.get());
|
Clang->createDiagnostics(&DC, false);
|
||||||
BufOwner.push_back(std::move(MB));
|
Clang->setTarget(TargetInfo::CreateTargetInfo(
|
||||||
}
|
Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
|
||||||
|
if (!Clang->hasTarget())
|
||||||
auto Unit = ASTUnit::create(CI, Diags, true, true);
|
|
||||||
if (!Unit)
|
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
FileConsumer file_consumer(vfs, file);
|
FileConsumer file_consumer(vfs, file);
|
||||||
IndexParam param(*Unit, &file_consumer);
|
IndexParam param(&file_consumer);
|
||||||
auto DataConsumer = std::make_shared<IndexDataConsumer>(param);
|
auto DataConsumer = std::make_shared<IndexDataConsumer>(param);
|
||||||
|
|
||||||
index::IndexingOptions IndexOpts;
|
index::IndexingOptions IndexOpts;
|
||||||
@ -1224,36 +1211,30 @@ Index(VFS *vfs, const std::string &opt_wdir, const std::string &file,
|
|||||||
IndexOpts.IndexImplicitInstantiation = true;
|
IndexOpts.IndexImplicitInstantiation = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::unique_ptr<FrontendAction> IndexAction = createIndexingAction(
|
std::unique_ptr<FrontendAction> Action = createIndexingAction(
|
||||||
DataConsumer, IndexOpts, std::make_unique<IndexFrontendAction>(param));
|
DataConsumer, IndexOpts, std::make_unique<IndexFrontendAction>(param));
|
||||||
|
|
||||||
DiagnosticErrorTrap DiagTrap(*Diags);
|
bool ok = false;
|
||||||
llvm::CrashRecoveryContext CRC;
|
{
|
||||||
auto compile = [&]() {
|
llvm::CrashRecoveryContext CRC;
|
||||||
ASTUnit::LoadFromCompilerInvocationAction(
|
auto parse = [&]() {
|
||||||
std::move(CI), PCHCO, Diags, IndexAction.get(), Unit.get(),
|
if (!Action->BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0]))
|
||||||
/*Persistent=*/true, /*ResourceDir=*/"",
|
return;
|
||||||
/*OnlyLocalDecls=*/true,
|
if (!Action->Execute())
|
||||||
/*CaptureDiagnostics=*/true, 0, false, false,
|
return;
|
||||||
/*UserFilesAreVolatile=*/true);
|
Action->EndSourceFile();
|
||||||
};
|
ok = true;
|
||||||
if (!CRC.RunSafely(compile)) {
|
};
|
||||||
LOG_S(ERROR) << "clang crashed for " << file;
|
if (!CRC.RunSafely(parse)) {
|
||||||
return {};
|
LOG_S(ERROR) << "clang crashed for " << file;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!Unit) {
|
if (!ok) {
|
||||||
LOG_S(ERROR) << "failed to index " << file;
|
LOG_S(ERROR) << "failed to index " << file;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const SourceManager &SM = Unit->getSourceManager();
|
|
||||||
const FileEntry *FE = SM.getFileEntryForID(SM.getMainFileID());
|
|
||||||
IndexFile *main_file = param.ConsumeFile(*FE);
|
|
||||||
std::unordered_map<std::string, int> inc_to_line;
|
|
||||||
if (main_file)
|
|
||||||
for (auto &inc : main_file->includes)
|
|
||||||
inc_to_line[inc.resolved_path] = inc.line;
|
|
||||||
|
|
||||||
auto result = param.file_consumer->TakeLocalState();
|
auto result = param.file_consumer->TakeLocalState();
|
||||||
for (std::unique_ptr<IndexFile> &entry : result) {
|
for (std::unique_ptr<IndexFile> &entry : result) {
|
||||||
entry->import_file = file;
|
entry->import_file = file;
|
||||||
@ -1276,22 +1257,6 @@ Index(VFS *vfs, const std::string &opt_wdir, const std::string &file,
|
|||||||
for (auto &it : entry->usr2var)
|
for (auto &it : entry->usr2var)
|
||||||
Uniquify(it.second.uses);
|
Uniquify(it.second.uses);
|
||||||
|
|
||||||
if (main_file) {
|
|
||||||
// If there are errors, show at least one at the include position.
|
|
||||||
auto it = inc_to_line.find(entry->path);
|
|
||||||
if (it != inc_to_line.end()) {
|
|
||||||
int line = it->second;
|
|
||||||
for (auto ls_diagnostic : entry->diagnostics_) {
|
|
||||||
if (ls_diagnostic.severity != lsDiagnosticSeverity::Error)
|
|
||||||
continue;
|
|
||||||
ls_diagnostic.range =
|
|
||||||
lsRange{lsPosition{line, 10}, lsPosition{line, 10}};
|
|
||||||
main_file->diagnostics_.push_back(ls_diagnostic);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update file contents and modification time.
|
// Update file contents and modification time.
|
||||||
entry->last_write_time = param.file2write_time[entry->path];
|
entry->last_write_time = param.file2write_time[entry->path];
|
||||||
|
|
||||||
|
@ -263,8 +263,6 @@ struct IndexFile {
|
|||||||
std::unordered_map<Usr, IndexType> usr2type;
|
std::unordered_map<Usr, IndexType> usr2type;
|
||||||
std::unordered_map<Usr, IndexVar> usr2var;
|
std::unordered_map<Usr, IndexVar> usr2var;
|
||||||
|
|
||||||
// Diagnostics found when indexing this file. Not serialized.
|
|
||||||
std::vector<lsDiagnostic> diagnostics_;
|
|
||||||
// File contents at the time of index. Not serialized.
|
// File contents at the time of index. Not serialized.
|
||||||
std::string file_contents;
|
std::string file_contents;
|
||||||
|
|
||||||
|
@ -255,12 +255,6 @@ bool Indexer_Parse(DiagnosticsPublisher *diag_pub, WorkingFiles *working_files,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (std::unique_ptr<IndexFile> &curr : indexes) {
|
for (std::unique_ptr<IndexFile> &curr : indexes) {
|
||||||
// Only emit diagnostics for non-interactive sessions, which makes it easier
|
|
||||||
// to identify indexing problems. For interactive sessions, diagnostics are
|
|
||||||
// handled by code completion.
|
|
||||||
if (!request.is_interactive)
|
|
||||||
diag_pub->Publish(working_files, curr->path, curr->diagnostics_);
|
|
||||||
|
|
||||||
std::string path = curr->path;
|
std::string path = curr->path;
|
||||||
if (!(vfs->Stamp(path, curr->last_write_time) || path == path_to_index))
|
if (!(vfs->Stamp(path, curr->last_write_time) || path == path_to_index))
|
||||||
continue;
|
continue;
|
||||||
|
@ -128,9 +128,6 @@ struct ProjectProcessor {
|
|||||||
|
|
||||||
args.push_back("-resource-dir=" + g_config->clang.resourceDir);
|
args.push_back("-resource-dir=" + g_config->clang.resourceDir);
|
||||||
args.push_back("-working-directory=" + entry.directory);
|
args.push_back("-working-directory=" + entry.directory);
|
||||||
// There could be a clang version mismatch between what the project uses and
|
|
||||||
// what ccls uses. Make sure we do not emit warnings for mismatched options.
|
|
||||||
args.push_back("-Wno-unknown-warning-option");
|
|
||||||
|
|
||||||
if (!command_set.insert(hash).second) {
|
if (!command_set.insert(hash).second) {
|
||||||
entry.args = std::move(args);
|
entry.args = std::move(args);
|
||||||
|
34
src/test.cc
34
src/test.cc
@ -307,42 +307,8 @@ bool RunIndexTests(const std::string &filter_path, bool enable_update) {
|
|||||||
const std::string &expected_path = entry.first;
|
const std::string &expected_path = entry.first;
|
||||||
std::string expected_output = text_replacer.Apply(entry.second);
|
std::string expected_output = text_replacer.Apply(entry.second);
|
||||||
|
|
||||||
// FIXME: promote to utils, find and remove duplicates (ie,
|
|
||||||
// ccls_call_tree.cc, maybe something in project.cc).
|
|
||||||
auto basename = [](const std::string &path) -> std::string {
|
|
||||||
size_t last_index = path.find_last_of('/');
|
|
||||||
if (last_index == std::string::npos)
|
|
||||||
return path;
|
|
||||||
return path.substr(last_index + 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get output from index operation.
|
// Get output from index operation.
|
||||||
IndexFile *db = FindDbForPathEnding(expected_path, dbs);
|
IndexFile *db = FindDbForPathEnding(expected_path, dbs);
|
||||||
if (db && !db->diagnostics_.empty()) {
|
|
||||||
printf("For %s\n", path.c_str());
|
|
||||||
for (const lsDiagnostic &diagnostic : db->diagnostics_) {
|
|
||||||
printf(" ");
|
|
||||||
if (diagnostic.severity)
|
|
||||||
switch (*diagnostic.severity) {
|
|
||||||
case lsDiagnosticSeverity::Error:
|
|
||||||
printf("error ");
|
|
||||||
break;
|
|
||||||
case lsDiagnosticSeverity::Warning:
|
|
||||||
printf("warning ");
|
|
||||||
break;
|
|
||||||
case lsDiagnosticSeverity::Information:
|
|
||||||
printf("information ");
|
|
||||||
break;
|
|
||||||
case lsDiagnosticSeverity::Hint:
|
|
||||||
printf("hint ");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
printf("%s:%s-%s:%s\n", basename(db->path).c_str(),
|
|
||||||
diagnostic.range.start.ToString().c_str(),
|
|
||||||
diagnostic.range.end.ToString().c_str(),
|
|
||||||
diagnostic.message.c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::string actual_output = "{}";
|
std::string actual_output = "{}";
|
||||||
if (db) {
|
if (db) {
|
||||||
VerifySerializeToFrom(db);
|
VerifySerializeToFrom(db);
|
||||||
|
Loading…
Reference in New Issue
Block a user