mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-29 02:51:57 +00:00
Remove <regex> from lex_utils.h and separate language_server_api.h
% time clang++ -fsyntax-only -std=c++11 a.cc <iostream> => 0.35s <regex> => 0.68s
This commit is contained in:
parent
411d49951d
commit
c68548a2ca
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "indexer.h"
|
#include "indexer.h"
|
||||||
#include "language_server_api.h"
|
#include "lsp.h"
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
|
|
||||||
#include <loguru/loguru.hpp>
|
#include <loguru/loguru.hpp>
|
||||||
|
@ -3,7 +3,8 @@
|
|||||||
#include "atomic_object.h"
|
#include "atomic_object.h"
|
||||||
#include "clang_index.h"
|
#include "clang_index.h"
|
||||||
#include "clang_translation_unit.h"
|
#include "clang_translation_unit.h"
|
||||||
#include "language_server_api_completion.h"
|
#include "lsp_completion.h"
|
||||||
|
#include "lsp_diagnostic.h"
|
||||||
#include "lru_cache.h"
|
#include "lru_cache.h"
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
#include "threaded_queue.h"
|
#include "threaded_queue.h"
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#if USE_CLANG_CXX
|
#if USE_CLANG_CXX
|
||||||
|
|
||||||
#include "language_server_api.h"
|
#include "lsp.h"
|
||||||
#include "working_files.h"
|
#include "working_files.h"
|
||||||
|
|
||||||
#include <clang/Format/Format.h>
|
#include <clang/Format/Format.h>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "language_server_api.h"
|
#include "lsp_diagnostic.h"
|
||||||
|
|
||||||
#include <clang-c/Index.h>
|
#include <clang-c/Index.h>
|
||||||
#if USE_CLANG_CXX
|
#if USE_CLANG_CXX
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "language_server_api_completion.h"
|
#include "lsp_completion.h"
|
||||||
|
|
||||||
#include <optional.h>
|
#include <optional.h>
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include "import_pipeline.h"
|
#include "import_pipeline.h"
|
||||||
#include "include_complete.h"
|
#include "include_complete.h"
|
||||||
#include "indexer.h"
|
#include "indexer.h"
|
||||||
#include "language_server_api.h"
|
#include "lsp_diagnostic.h"
|
||||||
#include "lex_utils.h"
|
#include "lex_utils.h"
|
||||||
#include "lru_cache.h"
|
#include "lru_cache.h"
|
||||||
#include "match.h"
|
#include "match.h"
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "iindexer.h"
|
#include "iindexer.h"
|
||||||
#include "import_manager.h"
|
#include "import_manager.h"
|
||||||
#include "language_server_api.h"
|
#include "lsp.h"
|
||||||
#include "message_handler.h"
|
#include "message_handler.h"
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "language_server_api_completion.h"
|
#include "lsp_completion.h"
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include "file_consumer.h"
|
#include "file_consumer.h"
|
||||||
#include "file_contents.h"
|
#include "file_contents.h"
|
||||||
#include "language.h"
|
#include "language.h"
|
||||||
#include "language_server_api.h"
|
#include "lsp.h"
|
||||||
#include "maybe.h"
|
#include "maybe.h"
|
||||||
#include "nt_string.h"
|
#include "nt_string.h"
|
||||||
#include "performance.h"
|
#include "performance.h"
|
||||||
|
@ -46,23 +46,6 @@ lsPosition CharPos(std::string_view search,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ParseIncludeLineResult ParseIncludeLine(const std::string& line) {
|
|
||||||
static const std::regex pattern(
|
|
||||||
"(\\s*)" // [1]: spaces before '#'
|
|
||||||
"#" //
|
|
||||||
"(\\s*)" // [2]: spaces after '#'
|
|
||||||
"([^\\s\"<]*)" // [3]: "include"
|
|
||||||
"(\\s*)" // [4]: spaces before quote
|
|
||||||
"([\"<])?" // [5]: the first quote char
|
|
||||||
"([^\\s\">]*)" // [6]: path of file
|
|
||||||
"[\">]?" //
|
|
||||||
"(.*)"); // [7]: suffix after quote char
|
|
||||||
std::smatch match;
|
|
||||||
bool ok = std::regex_match(line, match, pattern);
|
|
||||||
std::string text = match[3].str() + match[6].str();
|
|
||||||
return {ok, text, match};
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: eliminate |line_number| param.
|
// TODO: eliminate |line_number| param.
|
||||||
optional<lsRange> ExtractQuotedRange(int line_number, const std::string& line) {
|
optional<lsRange> ExtractQuotedRange(int line_number, const std::string& line) {
|
||||||
// Find starting and ending quote.
|
// Find starting and ending quote.
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "language_server_api.h"
|
#include "lsp.h"
|
||||||
|
|
||||||
#include <string_view.h>
|
#include <string_view.h>
|
||||||
|
|
||||||
#include <regex>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
@ -15,14 +14,6 @@ lsPosition CharPos(std::string_view search,
|
|||||||
char character,
|
char character,
|
||||||
int character_offset = 0);
|
int character_offset = 0);
|
||||||
|
|
||||||
struct ParseIncludeLineResult {
|
|
||||||
bool ok;
|
|
||||||
std::string text; // include the "include" part
|
|
||||||
std::smatch match;
|
|
||||||
};
|
|
||||||
|
|
||||||
ParseIncludeLineResult ParseIncludeLine(const std::string& line);
|
|
||||||
|
|
||||||
// TODO: eliminate |line_number| param.
|
// TODO: eliminate |line_number| param.
|
||||||
optional<lsRange> ExtractQuotedRange(int line_number, const std::string& line);
|
optional<lsRange> ExtractQuotedRange(int line_number, const std::string& line);
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "language_server_api.h"
|
#include "lsp.h"
|
||||||
|
|
||||||
#include "recorder.h"
|
#include "recorder.h"
|
||||||
#include "serializers/json.h"
|
#include "serializers/json.h"
|
@ -292,110 +292,12 @@ struct lsFormattingOptions {
|
|||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(lsFormattingOptions, tabSize, insertSpaces);
|
MAKE_REFLECT_STRUCT(lsFormattingOptions, tabSize, insertSpaces);
|
||||||
|
|
||||||
enum class lsDiagnosticSeverity {
|
|
||||||
// Reports an error.
|
|
||||||
Error = 1,
|
|
||||||
// Reports a warning.
|
|
||||||
Warning = 2,
|
|
||||||
// Reports an information.
|
|
||||||
Information = 3,
|
|
||||||
// Reports a hint.
|
|
||||||
Hint = 4
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_TYPE_PROXY(lsDiagnosticSeverity);
|
|
||||||
|
|
||||||
struct lsDiagnostic {
|
|
||||||
// The range at which the message applies.
|
|
||||||
lsRange range;
|
|
||||||
|
|
||||||
// The diagnostic's severity. Can be omitted. If omitted it is up to the
|
|
||||||
// client to interpret diagnostics as error, warning, info or hint.
|
|
||||||
optional<lsDiagnosticSeverity> severity;
|
|
||||||
|
|
||||||
// The diagnostic's code. Can be omitted.
|
|
||||||
int code = 0;
|
|
||||||
|
|
||||||
// A human-readable string describing the source of this
|
|
||||||
// diagnostic, e.g. 'typescript' or 'super lint'.
|
|
||||||
std::string source = "cquery";
|
|
||||||
|
|
||||||
// The diagnostic's message.
|
|
||||||
std::string message;
|
|
||||||
|
|
||||||
// Non-serialized set of fixits.
|
|
||||||
std::vector<lsTextEdit> fixits_;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(lsDiagnostic, range, severity, source, message);
|
|
||||||
|
|
||||||
enum class lsErrorCodes {
|
|
||||||
// Defined by JSON RPC
|
|
||||||
ParseError = -32700,
|
|
||||||
InvalidRequest = -32600,
|
|
||||||
MethodNotFound = -32601,
|
|
||||||
InvalidParams = -32602,
|
|
||||||
InternalError = -32603,
|
|
||||||
serverErrorStart = -32099,
|
|
||||||
serverErrorEnd = -32000,
|
|
||||||
ServerNotInitialized = -32002,
|
|
||||||
UnknownErrorCode = -32001,
|
|
||||||
|
|
||||||
// Defined by the protocol.
|
|
||||||
RequestCancelled = -32800,
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_TYPE_PROXY(lsErrorCodes);
|
|
||||||
struct Out_Error : public lsOutMessage<Out_Error> {
|
|
||||||
struct lsResponseError {
|
|
||||||
// A number indicating the error type that occurred.
|
|
||||||
lsErrorCodes code;
|
|
||||||
|
|
||||||
// A string providing a short description of the error.
|
|
||||||
std::string message;
|
|
||||||
|
|
||||||
// A Primitive or Structured value that contains additional
|
|
||||||
// information about the error. Can be omitted.
|
|
||||||
// optional<D> data;
|
|
||||||
};
|
|
||||||
|
|
||||||
lsRequestId id;
|
|
||||||
|
|
||||||
// The error object in case a request fails.
|
|
||||||
lsResponseError error;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Out_Error::lsResponseError, code, message);
|
|
||||||
MAKE_REFLECT_STRUCT(Out_Error, jsonrpc, id, error);
|
|
||||||
|
|
||||||
// Cancel an existing request.
|
// Cancel an existing request.
|
||||||
struct Ipc_CancelRequest : public RequestMessage<Ipc_CancelRequest> {
|
struct Ipc_CancelRequest : public RequestMessage<Ipc_CancelRequest> {
|
||||||
static const IpcId kIpcId = IpcId::CancelRequest;
|
static const IpcId kIpcId = IpcId::CancelRequest;
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(Ipc_CancelRequest, id);
|
MAKE_REFLECT_STRUCT(Ipc_CancelRequest, id);
|
||||||
|
|
||||||
// Diagnostics
|
|
||||||
struct Out_TextDocumentPublishDiagnostics
|
|
||||||
: public lsOutMessage<Out_TextDocumentPublishDiagnostics> {
|
|
||||||
struct Params {
|
|
||||||
// The URI for which diagnostic information is reported.
|
|
||||||
lsDocumentUri uri;
|
|
||||||
|
|
||||||
// An array of diagnostic information items.
|
|
||||||
std::vector<lsDiagnostic> diagnostics;
|
|
||||||
};
|
|
||||||
|
|
||||||
Params params;
|
|
||||||
};
|
|
||||||
template <typename TVisitor>
|
|
||||||
void Reflect(TVisitor& visitor, Out_TextDocumentPublishDiagnostics& value) {
|
|
||||||
std::string method = "textDocument/publishDiagnostics";
|
|
||||||
REFLECT_MEMBER_START();
|
|
||||||
REFLECT_MEMBER(jsonrpc);
|
|
||||||
REFLECT_MEMBER2("method", method);
|
|
||||||
REFLECT_MEMBER(params);
|
|
||||||
REFLECT_MEMBER_END();
|
|
||||||
}
|
|
||||||
MAKE_REFLECT_STRUCT(Out_TextDocumentPublishDiagnostics::Params,
|
|
||||||
uri,
|
|
||||||
diagnostics);
|
|
||||||
|
|
||||||
// MarkedString can be used to render human readable text. It is either a
|
// MarkedString can be used to render human readable text. It is either a
|
||||||
// markdown string or a code-block that provides a language and a code snippet.
|
// markdown string or a code-block that provides a language and a code snippet.
|
||||||
// The language identifier is sematically equal to the optional language
|
// The language identifier is sematically equal to the optional language
|
@ -1,5 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "language_server_api.h"
|
#include "lsp.h"
|
||||||
|
|
||||||
// The kind of a completion entry.
|
// The kind of a completion entry.
|
||||||
enum class lsCompletionItemKind {
|
enum class lsCompletionItemKind {
|
20
src/lsp_diagnostic.cc
Normal file
20
src/lsp_diagnostic.cc
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#include "lsp_diagnostic.h"
|
||||||
|
|
||||||
|
#include "queue_manager.h"
|
||||||
|
#include "working_files.h"
|
||||||
|
|
||||||
|
void EmitDiagnostics(WorkingFiles* working_files,
|
||||||
|
std::string path,
|
||||||
|
std::vector<lsDiagnostic> diagnostics) {
|
||||||
|
// Emit diagnostics.
|
||||||
|
Out_TextDocumentPublishDiagnostics out;
|
||||||
|
out.params.uri = lsDocumentUri::FromPath(path);
|
||||||
|
out.params.diagnostics = diagnostics;
|
||||||
|
QueueManager::WriteStdout(IpcId::TextDocumentPublishDiagnostics, out);
|
||||||
|
|
||||||
|
// Cache diagnostics so we can show fixits.
|
||||||
|
working_files->DoActionOnFile(path, [&](WorkingFile* working_file) {
|
||||||
|
if (working_file)
|
||||||
|
working_file->diagnostics_ = diagnostics;
|
||||||
|
});
|
||||||
|
}
|
106
src/lsp_diagnostic.h
Normal file
106
src/lsp_diagnostic.h
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "lsp.h"
|
||||||
|
|
||||||
|
enum class lsDiagnosticSeverity {
|
||||||
|
// Reports an error.
|
||||||
|
Error = 1,
|
||||||
|
// Reports a warning.
|
||||||
|
Warning = 2,
|
||||||
|
// Reports an information.
|
||||||
|
Information = 3,
|
||||||
|
// Reports a hint.
|
||||||
|
Hint = 4
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_TYPE_PROXY(lsDiagnosticSeverity);
|
||||||
|
|
||||||
|
struct lsDiagnostic {
|
||||||
|
// The range at which the message applies.
|
||||||
|
lsRange range;
|
||||||
|
|
||||||
|
// The diagnostic's severity. Can be omitted. If omitted it is up to the
|
||||||
|
// client to interpret diagnostics as error, warning, info or hint.
|
||||||
|
optional<lsDiagnosticSeverity> severity;
|
||||||
|
|
||||||
|
// The diagnostic's code. Can be omitted.
|
||||||
|
int code = 0;
|
||||||
|
|
||||||
|
// A human-readable string describing the source of this
|
||||||
|
// diagnostic, e.g. 'typescript' or 'super lint'.
|
||||||
|
std::string source = "cquery";
|
||||||
|
|
||||||
|
// The diagnostic's message.
|
||||||
|
std::string message;
|
||||||
|
|
||||||
|
// Non-serialized set of fixits.
|
||||||
|
std::vector<lsTextEdit> fixits_;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(lsDiagnostic, range, severity, source, message);
|
||||||
|
|
||||||
|
enum class lsErrorCodes {
|
||||||
|
// Defined by JSON RPC
|
||||||
|
ParseError = -32700,
|
||||||
|
InvalidRequest = -32600,
|
||||||
|
MethodNotFound = -32601,
|
||||||
|
InvalidParams = -32602,
|
||||||
|
InternalError = -32603,
|
||||||
|
serverErrorStart = -32099,
|
||||||
|
serverErrorEnd = -32000,
|
||||||
|
ServerNotInitialized = -32002,
|
||||||
|
UnknownErrorCode = -32001,
|
||||||
|
|
||||||
|
// Defined by the protocol.
|
||||||
|
RequestCancelled = -32800,
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_TYPE_PROXY(lsErrorCodes);
|
||||||
|
struct Out_Error : public lsOutMessage<Out_Error> {
|
||||||
|
struct lsResponseError {
|
||||||
|
// A number indicating the error type that occurred.
|
||||||
|
lsErrorCodes code;
|
||||||
|
|
||||||
|
// A string providing a short description of the error.
|
||||||
|
std::string message;
|
||||||
|
|
||||||
|
// A Primitive or Structured value that contains additional
|
||||||
|
// information about the error. Can be omitted.
|
||||||
|
// optional<D> data;
|
||||||
|
};
|
||||||
|
|
||||||
|
lsRequestId id;
|
||||||
|
|
||||||
|
// The error object in case a request fails.
|
||||||
|
lsResponseError error;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Out_Error::lsResponseError, code, message);
|
||||||
|
MAKE_REFLECT_STRUCT(Out_Error, jsonrpc, id, error);
|
||||||
|
|
||||||
|
// Diagnostics
|
||||||
|
struct Out_TextDocumentPublishDiagnostics
|
||||||
|
: public lsOutMessage<Out_TextDocumentPublishDiagnostics> {
|
||||||
|
struct Params {
|
||||||
|
// The URI for which diagnostic information is reported.
|
||||||
|
lsDocumentUri uri;
|
||||||
|
|
||||||
|
// An array of diagnostic information items.
|
||||||
|
std::vector<lsDiagnostic> diagnostics;
|
||||||
|
};
|
||||||
|
|
||||||
|
Params params;
|
||||||
|
};
|
||||||
|
template <typename TVisitor>
|
||||||
|
void Reflect(TVisitor& visitor, Out_TextDocumentPublishDiagnostics& value) {
|
||||||
|
std::string method = "textDocument/publishDiagnostics";
|
||||||
|
REFLECT_MEMBER_START();
|
||||||
|
REFLECT_MEMBER(jsonrpc);
|
||||||
|
REFLECT_MEMBER2("method", method);
|
||||||
|
REFLECT_MEMBER(params);
|
||||||
|
REFLECT_MEMBER_END();
|
||||||
|
}
|
||||||
|
MAKE_REFLECT_STRUCT(Out_TextDocumentPublishDiagnostics::Params,
|
||||||
|
uri,
|
||||||
|
diagnostics);
|
||||||
|
|
||||||
|
struct WorkingFiles;
|
||||||
|
void EmitDiagnostics(WorkingFiles* working_files,
|
||||||
|
std::string path,
|
||||||
|
std::vector<lsDiagnostic> diagnostics);
|
@ -1,6 +1,6 @@
|
|||||||
#include "match.h"
|
#include "match.h"
|
||||||
|
|
||||||
#include "language_server_api.h"
|
#include "lsp.h"
|
||||||
#include "queue_manager.h"
|
#include "queue_manager.h"
|
||||||
|
|
||||||
#include <doctest/doctest.h>
|
#include <doctest/doctest.h>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "ipc.h"
|
#include "ipc.h"
|
||||||
#include "language_server_api.h"
|
#include "lsp.h"
|
||||||
#include "query.h"
|
#include "query.h"
|
||||||
|
|
||||||
#include <optional.h>
|
#include <optional.h>
|
||||||
|
@ -128,7 +128,7 @@ struct CqueryRandomHandler : BaseMessageHandler<Ipc_CqueryRandom> {
|
|||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
sum += x[i];
|
sum += x[i];
|
||||||
if (sum >= roulette) {
|
if (sum >= roulette) {
|
||||||
Maybe<Use> use = GetDefinitionExtentOfSymbol(db, syms[i]);
|
Maybe<Use> use = GetDefinitionExtent(db, syms[i]);
|
||||||
if (!use)
|
if (!use)
|
||||||
continue;
|
continue;
|
||||||
if (auto ls_loc = GetLsLocationEx(db, working_files, *use,
|
if (auto ls_loc = GetLsLocationEx(db, working_files, *use,
|
||||||
|
@ -498,7 +498,7 @@ struct InitializeHandler : BaseMessageHandler<Ipc_InitializeRequest> {
|
|||||||
Reflect(json_reader, *config);
|
Reflect(json_reader, *config);
|
||||||
} catch (std::invalid_argument&) {
|
} catch (std::invalid_argument&) {
|
||||||
// This will not trigger because parse error is handled in
|
// This will not trigger because parse error is handled in
|
||||||
// MessageRegistry::Parse in language_server_api.cc
|
// MessageRegistry::Parse in lsp.cc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ struct TextDocumentCodeLensHandler
|
|||||||
// extent since that is better for outline. This tries to convert the
|
// extent since that is better for outline. This tries to convert the
|
||||||
// extent location to the spelling location.
|
// extent location to the spelling location.
|
||||||
auto try_ensure_spelling = [&](Use use) {
|
auto try_ensure_spelling = [&](Use use) {
|
||||||
Maybe<Use> def = GetDefinitionSpellingOfSymbol(db, use);
|
Maybe<Use> def = GetDefinitionSpell(db, use);
|
||||||
if (!def || def->range.start.line != use.range.start.line) {
|
if (!def || def->range.start.line != use.range.start.line) {
|
||||||
return use;
|
return use;
|
||||||
}
|
}
|
||||||
@ -214,7 +214,7 @@ struct TextDocumentCodeLensHandler
|
|||||||
|
|
||||||
// "Base"
|
// "Base"
|
||||||
if (def->base.size() == 1) {
|
if (def->base.size() == 1) {
|
||||||
Maybe<Use> base_loc = GetDefinitionSpellingOfSymbol(
|
Maybe<Use> base_loc = GetDefinitionSpell(
|
||||||
db, SymbolIdx{def->base[0], SymbolKind::Func});
|
db, SymbolIdx{def->base[0], SymbolKind::Func});
|
||||||
if (base_loc) {
|
if (base_loc) {
|
||||||
optional<lsLocation> ls_base =
|
optional<lsLocation> ls_base =
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
#include <loguru.hpp>
|
#include <loguru.hpp>
|
||||||
|
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// How a completion was triggered
|
// How a completion was triggered
|
||||||
@ -106,6 +108,29 @@ void DecorateIncludePaths(const std::smatch& match,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ParseIncludeLineResult {
|
||||||
|
bool ok;
|
||||||
|
std::string text; // include the "include" part
|
||||||
|
std::smatch match;
|
||||||
|
};
|
||||||
|
|
||||||
|
ParseIncludeLineResult ParseIncludeLine(const std::string& line) {
|
||||||
|
static const std::regex pattern(
|
||||||
|
"(\\s*)" // [1]: spaces before '#'
|
||||||
|
"#" //
|
||||||
|
"(\\s*)" // [2]: spaces after '#'
|
||||||
|
"([^\\s\"<]*)" // [3]: "include"
|
||||||
|
"(\\s*)" // [4]: spaces before quote
|
||||||
|
"([\"<])?" // [5]: the first quote char
|
||||||
|
"([^\\s\">]*)" // [6]: path of file
|
||||||
|
"[\">]?" //
|
||||||
|
"(.*)"); // [7]: suffix after quote char
|
||||||
|
std::smatch match;
|
||||||
|
bool ok = std::regex_match(line, match, pattern);
|
||||||
|
std::string text = match[3].str() + match[6].str();
|
||||||
|
return {ok, text, match};
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
char* tofixedbase64(T input, char* out) {
|
char* tofixedbase64(T input, char* out) {
|
||||||
const char* digits =
|
const char* digits =
|
||||||
|
@ -24,7 +24,7 @@ struct Out_TextDocumentDefinition
|
|||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(Out_TextDocumentDefinition, jsonrpc, id, result);
|
MAKE_REFLECT_STRUCT(Out_TextDocumentDefinition, jsonrpc, id, result);
|
||||||
|
|
||||||
std::vector<Use> GetGotoDefinitionTargets(QueryDatabase* db, SymbolRef sym) {
|
std::vector<Use> GetNonDefDeclarationTargets(QueryDatabase* db, SymbolRef sym) {
|
||||||
switch (sym.kind) {
|
switch (sym.kind) {
|
||||||
case SymbolKind::Var: {
|
case SymbolKind::Var: {
|
||||||
std::vector<Use> ret = GetNonDefDeclarations(db, sym);
|
std::vector<Use> ret = GetNonDefDeclarations(db, sym);
|
||||||
@ -32,7 +32,7 @@ std::vector<Use> GetGotoDefinitionTargets(QueryDatabase* db, SymbolRef sym) {
|
|||||||
if (ret.empty()) {
|
if (ret.empty()) {
|
||||||
for (auto& def : db->GetVar(sym).def)
|
for (auto& def : db->GetVar(sym).def)
|
||||||
if (def.type) {
|
if (def.type) {
|
||||||
if (Maybe<Use> use = GetDefinitionSpellingOfSymbol(
|
if (Maybe<Use> use = GetDefinitionSpell(
|
||||||
db, SymbolIdx{*def.type, SymbolKind::Type})) {
|
db, SymbolIdx{*def.type, SymbolKind::Type})) {
|
||||||
ret.push_back(*use);
|
ret.push_back(*use);
|
||||||
break;
|
break;
|
||||||
@ -99,7 +99,7 @@ struct TextDocumentDefinitionHandler
|
|||||||
|
|
||||||
if (uses.empty()) {
|
if (uses.empty()) {
|
||||||
// The symbol has no definition or the cursor is on a definition.
|
// The symbol has no definition or the cursor is on a definition.
|
||||||
uses = GetGotoDefinitionTargets(db, sym);
|
uses = GetNonDefDeclarationTargets(db, sym);
|
||||||
// There is no declaration but the cursor is on a definition.
|
// There is no declaration but the cursor is on a definition.
|
||||||
if (uses.empty() && on_def)
|
if (uses.empty() && on_def)
|
||||||
uses.push_back(*on_def);
|
uses.push_back(*on_def);
|
||||||
@ -143,7 +143,7 @@ struct TextDocumentDefinitionHandler
|
|||||||
auto pos = name.find(query);
|
auto pos = name.find(query);
|
||||||
if (pos == std::string::npos)
|
if (pos == std::string::npos)
|
||||||
continue;
|
continue;
|
||||||
Maybe<Use> use = GetDefinitionSpellingOfSymbol(db, db->symbols[i]);
|
Maybe<Use> use = GetDefinitionSpell(db, db->symbols[i]);
|
||||||
if (!use)
|
if (!use)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -157,7 +157,7 @@ struct TextDocumentDefinitionHandler
|
|||||||
}
|
}
|
||||||
if (best_i != -1) {
|
if (best_i != -1) {
|
||||||
Maybe<Use> use =
|
Maybe<Use> use =
|
||||||
GetDefinitionSpellingOfSymbol(db, db->symbols[best_i]);
|
GetDefinitionSpell(db, db->symbols[best_i]);
|
||||||
assert(use);
|
assert(use);
|
||||||
if (auto ls_loc = GetLsLocationEx(db, working_files, *use,
|
if (auto ls_loc = GetLsLocationEx(db, working_files, *use,
|
||||||
config->xref.container))
|
config->xref.container))
|
||||||
|
@ -23,7 +23,7 @@ bool InsertSymbolIntoResult(QueryDatabase* db,
|
|||||||
if (!info)
|
if (!info)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Maybe<Use> location = GetDefinitionExtentOfSymbol(db, symbol);
|
Maybe<Use> location = GetDefinitionExtent(db, symbol);
|
||||||
Use loc;
|
Use loc;
|
||||||
if (location)
|
if (location)
|
||||||
loc = *location;
|
loc = *location;
|
||||||
|
@ -40,13 +40,13 @@ std::vector<Use> GetDeclarations(std::vector<Q>& entities,
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
Maybe<Use> GetDefinitionSpellingOfSymbol(QueryDatabase* db, SymbolIdx sym) {
|
Maybe<Use> GetDefinitionSpell(QueryDatabase* db, SymbolIdx sym) {
|
||||||
Maybe<Use> ret;
|
Maybe<Use> ret;
|
||||||
EachEntityDef(db, sym, [&](const auto& def) { return !(ret = def.spell); });
|
EachEntityDef(db, sym, [&](const auto& def) { return !(ret = def.spell); });
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe<Use> GetDefinitionExtentOfSymbol(QueryDatabase* db, SymbolIdx sym) {
|
Maybe<Use> GetDefinitionExtent(QueryDatabase* db, SymbolIdx sym) {
|
||||||
// Used to jump to file.
|
// Used to jump to file.
|
||||||
if (sym.kind == SymbolKind::File)
|
if (sym.kind == SymbolKind::File)
|
||||||
return Use(Range(Position(0, 0), Position(0, 0)), sym.id, sym.kind,
|
return Use(Range(Position(0, 0), Position(0, 0)), sym.id, sym.kind,
|
||||||
@ -383,19 +383,3 @@ std::vector<SymbolRef> FindSymbolsAtLocation(WorkingFile* working_file,
|
|||||||
|
|
||||||
return symbols;
|
return symbols;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitDiagnostics(WorkingFiles* working_files,
|
|
||||||
std::string path,
|
|
||||||
std::vector<lsDiagnostic> diagnostics) {
|
|
||||||
// Emit diagnostics.
|
|
||||||
Out_TextDocumentPublishDiagnostics out;
|
|
||||||
out.params.uri = lsDocumentUri::FromPath(path);
|
|
||||||
out.params.diagnostics = diagnostics;
|
|
||||||
QueueManager::WriteStdout(IpcId::TextDocumentPublishDiagnostics, out);
|
|
||||||
|
|
||||||
// Cache diagnostics so we can show fixits.
|
|
||||||
working_files->DoActionOnFile(path, [&](WorkingFile* working_file) {
|
|
||||||
if (working_file)
|
|
||||||
working_file->diagnostics_ = diagnostics;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
|
|
||||||
#include <optional.h>
|
#include <optional.h>
|
||||||
|
|
||||||
Maybe<Use> GetDefinitionSpellingOfSymbol(QueryDatabase* db, SymbolIdx sym);
|
Maybe<Use> GetDefinitionSpell(QueryDatabase* db, SymbolIdx sym);
|
||||||
Maybe<Use> GetDefinitionExtentOfSymbol(QueryDatabase* db, SymbolIdx sym);
|
Maybe<Use> GetDefinitionExtent(QueryDatabase* db, SymbolIdx sym);
|
||||||
Maybe<QueryFileId> GetDeclarationFileForSymbol(QueryDatabase* db,
|
Maybe<QueryFileId> GetDeclarationFileForSymbol(QueryDatabase* db,
|
||||||
SymbolIdx sym);
|
SymbolIdx sym);
|
||||||
|
|
||||||
@ -53,10 +53,6 @@ std::vector<SymbolRef> FindSymbolsAtLocation(WorkingFile* working_file,
|
|||||||
QueryFile* file,
|
QueryFile* file,
|
||||||
lsPosition position);
|
lsPosition position);
|
||||||
|
|
||||||
void EmitDiagnostics(WorkingFiles* working_files,
|
|
||||||
std::string path,
|
|
||||||
std::vector<lsDiagnostic> diagnostics);
|
|
||||||
|
|
||||||
template <typename Fn>
|
template <typename Fn>
|
||||||
void WithEntity(QueryDatabase* db, SymbolIdx sym, Fn&& fn) {
|
void WithEntity(QueryDatabase* db, SymbolIdx sym, Fn&& fn) {
|
||||||
switch (sym.kind) {
|
switch (sym.kind) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "queue_manager.h"
|
#include "queue_manager.h"
|
||||||
|
|
||||||
#include "cache_manager.h"
|
#include "cache_manager.h"
|
||||||
#include "language_server_api.h"
|
#include "lsp.h"
|
||||||
#include "query.h"
|
#include "query.h"
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "language_server_api.h"
|
#include "lsp_diagnostic.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
#include <clang-c/Index.h>
|
#include <clang-c/Index.h>
|
||||||
|
Loading…
Reference in New Issue
Block a user