mirror of
https://github.com/MaskRay/ccls.git
synced 2025-04-14 21:02:14 +00:00
Move Ipc_* types into messages/
This commit is contained in:
parent
5093863b33
commit
b65a30c3f7
@ -424,8 +424,10 @@ void CompletionQueryMain(ClangCompleteManager* completion_manager) {
|
|||||||
ls_completion_item.insertTextFormat,
|
ls_completion_item.insertTextFormat,
|
||||||
&ls_completion_item.parameters_,
|
&ls_completion_item.parameters_,
|
||||||
completion_manager->config_->enableSnippetInsertion);
|
completion_manager->config_->enableSnippetInsertion);
|
||||||
if (ls_completion_item.insertTextFormat == lsInsertTextFormat::Snippet)
|
if (ls_completion_item.insertTextFormat ==
|
||||||
ls_completion_item.insertText += "$0";
|
lsInsertTextFormat::Snippet) {
|
||||||
|
ls_completion_item.insertText += "$0";
|
||||||
|
}
|
||||||
|
|
||||||
ls_completion_item.documentation = ToString(
|
ls_completion_item.documentation = ToString(
|
||||||
clang_getCompletionBriefComment(result.CompletionString));
|
clang_getCompletionBriefComment(result.CompletionString));
|
||||||
|
@ -86,36 +86,6 @@ void EmitDiagnostics(WorkingFiles* working_files,
|
|||||||
}
|
}
|
||||||
|
|
||||||
REGISTER_IPC_MESSAGE(Ipc_CancelRequest);
|
REGISTER_IPC_MESSAGE(Ipc_CancelRequest);
|
||||||
REGISTER_IPC_MESSAGE(Ipc_Exit);
|
|
||||||
REGISTER_IPC_MESSAGE(Ipc_TextDocumentDidOpen);
|
|
||||||
REGISTER_IPC_MESSAGE(Ipc_CqueryTextDocumentDidView);
|
|
||||||
REGISTER_IPC_MESSAGE(Ipc_TextDocumentDidChange);
|
|
||||||
REGISTER_IPC_MESSAGE(Ipc_TextDocumentDidClose);
|
|
||||||
REGISTER_IPC_MESSAGE(Ipc_TextDocumentDidSave);
|
|
||||||
REGISTER_IPC_MESSAGE(Ipc_TextDocumentRename);
|
|
||||||
REGISTER_IPC_MESSAGE(Ipc_TextDocumentComplete);
|
|
||||||
REGISTER_IPC_MESSAGE(Ipc_TextDocumentSignatureHelp);
|
|
||||||
REGISTER_IPC_MESSAGE(Ipc_TextDocumentDefinition);
|
|
||||||
REGISTER_IPC_MESSAGE(Ipc_TextDocumentDocumentHighlight);
|
|
||||||
REGISTER_IPC_MESSAGE(Ipc_TextDocumentHover);
|
|
||||||
REGISTER_IPC_MESSAGE(Ipc_TextDocumentReferences);
|
|
||||||
REGISTER_IPC_MESSAGE(Ipc_TextDocumentDocumentSymbol);
|
|
||||||
REGISTER_IPC_MESSAGE(Ipc_TextDocumentDocumentLink);
|
|
||||||
REGISTER_IPC_MESSAGE(Ipc_TextDocumentCodeAction);
|
|
||||||
REGISTER_IPC_MESSAGE(Ipc_TextDocumentCodeLens);
|
|
||||||
REGISTER_IPC_MESSAGE(Ipc_CodeLensResolve);
|
|
||||||
REGISTER_IPC_MESSAGE(Ipc_WorkspaceSymbol);
|
|
||||||
REGISTER_IPC_MESSAGE(Ipc_CqueryFreshenIndex);
|
|
||||||
REGISTER_IPC_MESSAGE(Ipc_CqueryTypeHierarchyTree);
|
|
||||||
REGISTER_IPC_MESSAGE(Ipc_CqueryCallTreeInitial);
|
|
||||||
REGISTER_IPC_MESSAGE(Ipc_CqueryCallTreeExpand);
|
|
||||||
REGISTER_IPC_MESSAGE(Ipc_CqueryVars);
|
|
||||||
REGISTER_IPC_MESSAGE(Ipc_CqueryCallers);
|
|
||||||
REGISTER_IPC_MESSAGE(Ipc_CqueryBase);
|
|
||||||
REGISTER_IPC_MESSAGE(Ipc_CqueryDerived);
|
|
||||||
REGISTER_IPC_MESSAGE(Ipc_CqueryIndexFile);
|
|
||||||
REGISTER_IPC_MESSAGE(Ipc_CqueryQueryDbWaitForIdleIndexer);
|
|
||||||
REGISTER_IPC_MESSAGE(Ipc_CqueryExitWhenIdle);
|
|
||||||
|
|
||||||
// Send indexing progress to client if reporting is enabled.
|
// Send indexing progress to client if reporting is enabled.
|
||||||
void EmitProgress(Config* config, QueueManager* queue) {
|
void EmitProgress(Config* config, QueueManager* queue) {
|
||||||
|
31
src/ipc.h
31
src/ipc.h
@ -78,33 +78,4 @@ struct BaseIpcMessage {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
struct IpcMessage : public BaseIpcMessage {
|
struct IpcMessage : public BaseIpcMessage {
|
||||||
IpcMessage() : BaseIpcMessage(T::kIpcId) {}
|
IpcMessage() : BaseIpcMessage(T::kIpcId) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Ipc_CqueryIndexFile : public IpcMessage<Ipc_CqueryIndexFile> {
|
|
||||||
static constexpr IpcId kIpcId = IpcId::CqueryIndexFile;
|
|
||||||
|
|
||||||
struct Params {
|
|
||||||
std::string path;
|
|
||||||
std::vector<std::string> args;
|
|
||||||
bool is_interactive = false;
|
|
||||||
std::string contents;
|
|
||||||
};
|
|
||||||
Params params;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_CqueryIndexFile::Params,
|
|
||||||
path,
|
|
||||||
args,
|
|
||||||
is_interactive,
|
|
||||||
contents);
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_CqueryIndexFile, params);
|
|
||||||
|
|
||||||
struct Ipc_CqueryQueryDbWaitForIdleIndexer
|
|
||||||
: public IpcMessage<Ipc_CqueryQueryDbWaitForIdleIndexer> {
|
|
||||||
static constexpr IpcId kIpcId = IpcId::CqueryQueryDbWaitForIdleIndexer;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_EMPTY_STRUCT(Ipc_CqueryQueryDbWaitForIdleIndexer);
|
|
||||||
|
|
||||||
struct Ipc_CqueryExitWhenIdle : public IpcMessage<Ipc_CqueryExitWhenIdle> {
|
|
||||||
static constexpr IpcId kIpcId = IpcId::CqueryExitWhenIdle;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_EMPTY_STRUCT(Ipc_CqueryExitWhenIdle);
|
|
@ -338,22 +338,6 @@ void Reflect(Writer& writer, lsInitializeParams::lsTrace& value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reflect(Writer& visitor, lsCodeLensCommandArguments& value) {
|
|
||||||
visitor.StartArray();
|
|
||||||
Reflect(visitor, value.uri);
|
|
||||||
Reflect(visitor, value.position);
|
|
||||||
Reflect(visitor, value.locations);
|
|
||||||
visitor.EndArray();
|
|
||||||
}
|
|
||||||
void Reflect(Reader& visitor, lsCodeLensCommandArguments& value) {
|
|
||||||
auto it = visitor.Begin();
|
|
||||||
Reflect(*it, value.uri);
|
|
||||||
++it;
|
|
||||||
Reflect(*it, value.position);
|
|
||||||
++it;
|
|
||||||
Reflect(*it, value.locations);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Out_ShowLogMessage::method() {
|
std::string Out_ShowLogMessage::method() {
|
||||||
if (display_type == DisplayType::Log)
|
if (display_type == DisplayType::Log)
|
||||||
return "window/logMessage";
|
return "window/logMessage";
|
||||||
|
@ -899,11 +899,6 @@ MAKE_REFLECT_STRUCT(lsServerCapabilities,
|
|||||||
documentLinkProvider,
|
documentLinkProvider,
|
||||||
executeCommandProvider);
|
executeCommandProvider);
|
||||||
|
|
||||||
struct Ipc_Exit : public IpcMessage<Ipc_Exit> {
|
|
||||||
static const IpcId kIpcId = IpcId::Exit;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_EMPTY_STRUCT(Ipc_Exit);
|
|
||||||
|
|
||||||
enum class lsErrorCodes {
|
enum class lsErrorCodes {
|
||||||
// Defined by JSON RPC
|
// Defined by JSON RPC
|
||||||
ParseError = -32700,
|
ParseError = -32700,
|
||||||
@ -948,82 +943,6 @@ struct Ipc_CancelRequest : public IpcMessage<Ipc_CancelRequest> {
|
|||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(Ipc_CancelRequest, id);
|
MAKE_REFLECT_STRUCT(Ipc_CancelRequest, id);
|
||||||
|
|
||||||
// Open, view, change, close file
|
|
||||||
struct Ipc_TextDocumentDidOpen : public IpcMessage<Ipc_TextDocumentDidOpen> {
|
|
||||||
struct Params {
|
|
||||||
lsTextDocumentItem textDocument;
|
|
||||||
};
|
|
||||||
|
|
||||||
const static IpcId kIpcId = IpcId::TextDocumentDidOpen;
|
|
||||||
Params params;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_TextDocumentDidOpen::Params, textDocument);
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_TextDocumentDidOpen, params);
|
|
||||||
struct Ipc_CqueryTextDocumentDidView
|
|
||||||
: public IpcMessage<Ipc_CqueryTextDocumentDidView> {
|
|
||||||
struct Params {
|
|
||||||
lsDocumentUri textDocumentUri;
|
|
||||||
};
|
|
||||||
|
|
||||||
const static IpcId kIpcId = IpcId::CqueryTextDocumentDidView;
|
|
||||||
Params params;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_CqueryTextDocumentDidView::Params, textDocumentUri);
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_CqueryTextDocumentDidView, params);
|
|
||||||
struct Ipc_TextDocumentDidChange
|
|
||||||
: public IpcMessage<Ipc_TextDocumentDidChange> {
|
|
||||||
struct lsTextDocumentContentChangeEvent {
|
|
||||||
// The range of the document that changed.
|
|
||||||
lsRange range;
|
|
||||||
// The length of the range that got replaced.
|
|
||||||
int rangeLength = -1;
|
|
||||||
// The new text of the range/document.
|
|
||||||
std::string text;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Params {
|
|
||||||
lsVersionedTextDocumentIdentifier textDocument;
|
|
||||||
std::vector<lsTextDocumentContentChangeEvent> contentChanges;
|
|
||||||
};
|
|
||||||
|
|
||||||
const static IpcId kIpcId = IpcId::TextDocumentDidChange;
|
|
||||||
Params params;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_TextDocumentDidChange::lsTextDocumentContentChangeEvent,
|
|
||||||
range,
|
|
||||||
rangeLength,
|
|
||||||
text);
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_TextDocumentDidChange::Params,
|
|
||||||
textDocument,
|
|
||||||
contentChanges);
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_TextDocumentDidChange, params);
|
|
||||||
struct Ipc_TextDocumentDidClose : public IpcMessage<Ipc_TextDocumentDidClose> {
|
|
||||||
struct Params {
|
|
||||||
lsTextDocumentItem textDocument;
|
|
||||||
};
|
|
||||||
|
|
||||||
const static IpcId kIpcId = IpcId::TextDocumentDidClose;
|
|
||||||
Params params;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_TextDocumentDidClose::Params, textDocument);
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_TextDocumentDidClose, params);
|
|
||||||
|
|
||||||
struct Ipc_TextDocumentDidSave : public IpcMessage<Ipc_TextDocumentDidSave> {
|
|
||||||
struct Params {
|
|
||||||
// The document that was saved.
|
|
||||||
lsTextDocumentIdentifier textDocument;
|
|
||||||
|
|
||||||
// Optional the content when saved. Depends on the includeText value
|
|
||||||
// when the save notifcation was requested.
|
|
||||||
// std::string text;
|
|
||||||
};
|
|
||||||
|
|
||||||
const static IpcId kIpcId = IpcId::TextDocumentDidSave;
|
|
||||||
Params params;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_TextDocumentDidSave::Params, textDocument);
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_TextDocumentDidSave, params);
|
|
||||||
|
|
||||||
// Diagnostics
|
// Diagnostics
|
||||||
struct Out_TextDocumentPublishDiagnostics
|
struct Out_TextDocumentPublishDiagnostics
|
||||||
: public lsOutMessage<Out_TextDocumentPublishDiagnostics> {
|
: public lsOutMessage<Out_TextDocumentPublishDiagnostics> {
|
||||||
@ -1050,126 +969,6 @@ MAKE_REFLECT_STRUCT(Out_TextDocumentPublishDiagnostics::Params,
|
|||||||
uri,
|
uri,
|
||||||
diagnostics);
|
diagnostics);
|
||||||
|
|
||||||
// Rename
|
|
||||||
struct Ipc_TextDocumentRename : public IpcMessage<Ipc_TextDocumentRename> {
|
|
||||||
struct Params {
|
|
||||||
// The document to format.
|
|
||||||
lsTextDocumentIdentifier textDocument;
|
|
||||||
|
|
||||||
// The position at which this request was sent.
|
|
||||||
lsPosition position;
|
|
||||||
|
|
||||||
// The new name of the symbol. If the given name is not valid the
|
|
||||||
// request must return a [ResponseError](#ResponseError) with an
|
|
||||||
// appropriate message set.
|
|
||||||
std::string newName;
|
|
||||||
};
|
|
||||||
const static IpcId kIpcId = IpcId::TextDocumentRename;
|
|
||||||
|
|
||||||
lsRequestId id;
|
|
||||||
Params params;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_TextDocumentRename::Params,
|
|
||||||
textDocument,
|
|
||||||
position,
|
|
||||||
newName);
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_TextDocumentRename, id, params);
|
|
||||||
struct Out_TextDocumentRename : public lsOutMessage<Out_TextDocumentRename> {
|
|
||||||
lsRequestId id;
|
|
||||||
lsWorkspaceEdit result;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Out_TextDocumentRename, jsonrpc, id, result);
|
|
||||||
|
|
||||||
// Code completion
|
|
||||||
struct Ipc_TextDocumentComplete : public IpcMessage<Ipc_TextDocumentComplete> {
|
|
||||||
const static IpcId kIpcId = IpcId::TextDocumentCompletion;
|
|
||||||
|
|
||||||
lsRequestId id;
|
|
||||||
lsTextDocumentPositionParams params;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_TextDocumentComplete, id, params);
|
|
||||||
struct lsTextDocumentCompleteResult {
|
|
||||||
// This list it not complete. Further typing should result in recomputing
|
|
||||||
// this list.
|
|
||||||
bool isIncomplete = false;
|
|
||||||
// The completion items.
|
|
||||||
NonElidedVector<lsCompletionItem> items;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(lsTextDocumentCompleteResult, isIncomplete, items);
|
|
||||||
struct Out_TextDocumentComplete
|
|
||||||
: public lsOutMessage<Out_TextDocumentComplete> {
|
|
||||||
lsRequestId id;
|
|
||||||
lsTextDocumentCompleteResult result;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Out_TextDocumentComplete, jsonrpc, id, result);
|
|
||||||
|
|
||||||
// Signature help.
|
|
||||||
struct Ipc_TextDocumentSignatureHelp
|
|
||||||
: public IpcMessage<Ipc_TextDocumentSignatureHelp> {
|
|
||||||
const static IpcId kIpcId = IpcId::TextDocumentSignatureHelp;
|
|
||||||
|
|
||||||
lsRequestId id;
|
|
||||||
lsTextDocumentPositionParams params;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_TextDocumentSignatureHelp, id, params);
|
|
||||||
// Represents a parameter of a callable-signature. A parameter can
|
|
||||||
// have a label and a doc-comment.
|
|
||||||
struct lsParameterInformation {
|
|
||||||
// The label of this parameter. Will be shown in
|
|
||||||
// the UI.
|
|
||||||
std::string label;
|
|
||||||
|
|
||||||
// The human-readable doc-comment of this parameter. Will be shown
|
|
||||||
// in the UI but can be omitted.
|
|
||||||
optional<std::string> documentation;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(lsParameterInformation, label, documentation);
|
|
||||||
// Represents the signature of something callable. A signature
|
|
||||||
// can have a label, like a function-name, a doc-comment, and
|
|
||||||
// a set of parameters.
|
|
||||||
struct lsSignatureInformation {
|
|
||||||
// The label of this signature. Will be shown in
|
|
||||||
// the UI.
|
|
||||||
std::string label;
|
|
||||||
|
|
||||||
// The human-readable doc-comment of this signature. Will be shown
|
|
||||||
// in the UI but can be omitted.
|
|
||||||
optional<std::string> documentation;
|
|
||||||
|
|
||||||
// The parameters of this signature.
|
|
||||||
std::vector<lsParameterInformation> parameters;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(lsSignatureInformation, label, documentation, parameters);
|
|
||||||
// Signature help represents the signature of something
|
|
||||||
// callable. There can be multiple signature but only one
|
|
||||||
// active and only one active parameter.
|
|
||||||
struct lsSignatureHelp {
|
|
||||||
// One or more signatures.
|
|
||||||
NonElidedVector<lsSignatureInformation> signatures;
|
|
||||||
|
|
||||||
// The active signature. If omitted or the value lies outside the
|
|
||||||
// range of `signatures` the value defaults to zero or is ignored if
|
|
||||||
// `signatures.length === 0`. Whenever possible implementors should
|
|
||||||
// make an active decision about the active signature and shouldn't
|
|
||||||
// rely on a default value.
|
|
||||||
// In future version of the protocol this property might become
|
|
||||||
// mandantory to better express this.
|
|
||||||
optional<int> activeSignature;
|
|
||||||
|
|
||||||
// The active parameter of the active signature. If omitted or the value
|
|
||||||
// lies outside the range of `signatures[activeSignature].parameters`
|
|
||||||
// defaults to 0 if the active signature has parameters. If
|
|
||||||
// the active signature has no parameters it is ignored.
|
|
||||||
// In future version of the protocol this property might become
|
|
||||||
// mandantory to better express the active parameter if the
|
|
||||||
// active signature does have any.
|
|
||||||
optional<int> activeParameter;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(lsSignatureHelp,
|
|
||||||
signatures,
|
|
||||||
activeSignature,
|
|
||||||
activeParameter);
|
|
||||||
|
|
||||||
// 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
|
||||||
@ -1189,252 +988,23 @@ struct lsMarkedString {
|
|||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(lsMarkedString, language, value);
|
MAKE_REFLECT_STRUCT(lsMarkedString, language, value);
|
||||||
|
|
||||||
struct Out_TextDocumentSignatureHelp
|
struct lsTextDocumentContentChangeEvent {
|
||||||
: public lsOutMessage<Out_TextDocumentSignatureHelp> {
|
// The range of the document that changed.
|
||||||
lsRequestId id;
|
|
||||||
lsSignatureHelp result;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Out_TextDocumentSignatureHelp, jsonrpc, id, result);
|
|
||||||
|
|
||||||
// Goto definition
|
|
||||||
struct Ipc_TextDocumentDefinition
|
|
||||||
: public IpcMessage<Ipc_TextDocumentDefinition> {
|
|
||||||
const static IpcId kIpcId = IpcId::TextDocumentDefinition;
|
|
||||||
|
|
||||||
lsRequestId id;
|
|
||||||
lsTextDocumentPositionParams params;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_TextDocumentDefinition, id, params);
|
|
||||||
struct Out_TextDocumentDefinition
|
|
||||||
: public lsOutMessage<Out_TextDocumentDefinition> {
|
|
||||||
lsRequestId id;
|
|
||||||
NonElidedVector<lsLocation> result;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Out_TextDocumentDefinition, jsonrpc, id, result);
|
|
||||||
|
|
||||||
// Document highlight
|
|
||||||
struct Ipc_TextDocumentDocumentHighlight
|
|
||||||
: public IpcMessage<Ipc_TextDocumentDocumentHighlight> {
|
|
||||||
const static IpcId kIpcId = IpcId::TextDocumentDocumentHighlight;
|
|
||||||
|
|
||||||
lsRequestId id;
|
|
||||||
lsTextDocumentPositionParams params;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_TextDocumentDocumentHighlight, id, params);
|
|
||||||
struct Out_TextDocumentDocumentHighlight
|
|
||||||
: public lsOutMessage<Out_TextDocumentDocumentHighlight> {
|
|
||||||
lsRequestId id;
|
|
||||||
NonElidedVector<lsDocumentHighlight> result;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Out_TextDocumentDocumentHighlight, jsonrpc, id, result);
|
|
||||||
|
|
||||||
// Hover
|
|
||||||
struct Ipc_TextDocumentHover : public IpcMessage<Ipc_TextDocumentHover> {
|
|
||||||
const static IpcId kIpcId = IpcId::TextDocumentHover;
|
|
||||||
|
|
||||||
lsRequestId id;
|
|
||||||
lsTextDocumentPositionParams params;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_TextDocumentHover, id, params);
|
|
||||||
struct Out_TextDocumentHover : public lsOutMessage<Out_TextDocumentHover> {
|
|
||||||
struct Result {
|
|
||||||
lsMarkedString contents;
|
|
||||||
optional<lsRange> range;
|
|
||||||
};
|
|
||||||
|
|
||||||
lsRequestId id;
|
|
||||||
Result result;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Out_TextDocumentHover::Result, contents, range);
|
|
||||||
MAKE_REFLECT_STRUCT(Out_TextDocumentHover, jsonrpc, id, result);
|
|
||||||
|
|
||||||
// References
|
|
||||||
struct Ipc_TextDocumentReferences
|
|
||||||
: public IpcMessage<Ipc_TextDocumentReferences> {
|
|
||||||
struct lsReferenceContext {
|
|
||||||
// Include the declaration of the current symbol.
|
|
||||||
bool includeDeclaration;
|
|
||||||
};
|
|
||||||
struct lsReferenceParams : public lsTextDocumentPositionParams {
|
|
||||||
lsTextDocumentIdentifier textDocument;
|
|
||||||
lsPosition position;
|
|
||||||
lsReferenceContext context;
|
|
||||||
};
|
|
||||||
|
|
||||||
const static IpcId kIpcId = IpcId::TextDocumentReferences;
|
|
||||||
|
|
||||||
lsRequestId id;
|
|
||||||
lsReferenceParams params;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_TextDocumentReferences::lsReferenceContext,
|
|
||||||
includeDeclaration);
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_TextDocumentReferences::lsReferenceParams,
|
|
||||||
textDocument,
|
|
||||||
position,
|
|
||||||
context);
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_TextDocumentReferences, id, params);
|
|
||||||
struct Out_TextDocumentReferences
|
|
||||||
: public lsOutMessage<Out_TextDocumentReferences> {
|
|
||||||
lsRequestId id;
|
|
||||||
NonElidedVector<lsLocation> result;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Out_TextDocumentReferences, jsonrpc, id, result);
|
|
||||||
|
|
||||||
// Code action
|
|
||||||
struct Ipc_TextDocumentCodeAction
|
|
||||||
: public IpcMessage<Ipc_TextDocumentCodeAction> {
|
|
||||||
const static IpcId kIpcId = IpcId::TextDocumentCodeAction;
|
|
||||||
// Contains additional diagnostic information about the context in which
|
|
||||||
// a code action is run.
|
|
||||||
struct lsCodeActionContext {
|
|
||||||
// An array of diagnostics.
|
|
||||||
NonElidedVector<lsDiagnostic> diagnostics;
|
|
||||||
};
|
|
||||||
// Params for the CodeActionRequest
|
|
||||||
struct lsCodeActionParams {
|
|
||||||
// The document in which the command was invoked.
|
|
||||||
lsTextDocumentIdentifier textDocument;
|
|
||||||
// The range for which the command was invoked.
|
|
||||||
lsRange range;
|
|
||||||
// Context carrying additional information.
|
|
||||||
lsCodeActionContext context;
|
|
||||||
};
|
|
||||||
|
|
||||||
lsRequestId id;
|
|
||||||
lsCodeActionParams params;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_TextDocumentCodeAction::lsCodeActionContext,
|
|
||||||
diagnostics);
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_TextDocumentCodeAction::lsCodeActionParams,
|
|
||||||
textDocument,
|
|
||||||
range,
|
|
||||||
context);
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_TextDocumentCodeAction, id, params);
|
|
||||||
struct Out_TextDocumentCodeAction
|
|
||||||
: public lsOutMessage<Out_TextDocumentCodeAction> {
|
|
||||||
struct CommandArgs {
|
|
||||||
lsDocumentUri textDocumentUri;
|
|
||||||
NonElidedVector<lsTextEdit> edits;
|
|
||||||
};
|
|
||||||
using Command = lsCommand<CommandArgs>;
|
|
||||||
|
|
||||||
lsRequestId id;
|
|
||||||
NonElidedVector<Command> result;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT_WRITER_AS_ARRAY(Out_TextDocumentCodeAction::CommandArgs,
|
|
||||||
textDocumentUri,
|
|
||||||
edits);
|
|
||||||
MAKE_REFLECT_STRUCT(Out_TextDocumentCodeAction, jsonrpc, id, result);
|
|
||||||
|
|
||||||
// List symbols in a document.
|
|
||||||
struct lsDocumentSymbolParams {
|
|
||||||
lsTextDocumentIdentifier textDocument;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(lsDocumentSymbolParams, textDocument);
|
|
||||||
struct Ipc_TextDocumentDocumentSymbol
|
|
||||||
: public IpcMessage<Ipc_TextDocumentDocumentSymbol> {
|
|
||||||
const static IpcId kIpcId = IpcId::TextDocumentDocumentSymbol;
|
|
||||||
|
|
||||||
lsRequestId id;
|
|
||||||
lsDocumentSymbolParams params;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_TextDocumentDocumentSymbol, id, params);
|
|
||||||
struct Out_TextDocumentDocumentSymbol
|
|
||||||
: public lsOutMessage<Out_TextDocumentDocumentSymbol> {
|
|
||||||
lsRequestId id;
|
|
||||||
NonElidedVector<lsSymbolInformation> result;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Out_TextDocumentDocumentSymbol, jsonrpc, id, result);
|
|
||||||
|
|
||||||
// List links a document
|
|
||||||
struct Ipc_TextDocumentDocumentLink
|
|
||||||
: public IpcMessage<Ipc_TextDocumentDocumentLink> {
|
|
||||||
const static IpcId kIpcId = IpcId::TextDocumentDocumentLink;
|
|
||||||
|
|
||||||
struct DocumentLinkParams {
|
|
||||||
// The document to provide document links for.
|
|
||||||
lsTextDocumentIdentifier textDocument;
|
|
||||||
};
|
|
||||||
|
|
||||||
lsRequestId id;
|
|
||||||
DocumentLinkParams params;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_TextDocumentDocumentLink::DocumentLinkParams,
|
|
||||||
textDocument);
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_TextDocumentDocumentLink, id, params);
|
|
||||||
// A document link is a range in a text document that links to an internal or
|
|
||||||
// external resource, like another text document or a web site.
|
|
||||||
struct lsDocumentLink {
|
|
||||||
// The range this link applies to.
|
|
||||||
lsRange range;
|
lsRange range;
|
||||||
// The uri this link points to. If missing a resolve request is sent later.
|
// The length of the range that got replaced.
|
||||||
optional<lsDocumentUri> target;
|
int rangeLength = -1;
|
||||||
|
// The new text of the range/document.
|
||||||
|
std::string text;
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(lsDocumentLink, range, target);
|
MAKE_REFLECT_STRUCT(lsTextDocumentContentChangeEvent, range, rangeLength, text);
|
||||||
struct Out_TextDocumentDocumentLink
|
|
||||||
: public lsOutMessage<Out_TextDocumentDocumentLink> {
|
|
||||||
lsRequestId id;
|
|
||||||
NonElidedVector<lsDocumentLink> result;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Out_TextDocumentDocumentLink, jsonrpc, id, result);
|
|
||||||
|
|
||||||
// List code lens in a document.
|
struct lsTextDocumentDidChangeParams {
|
||||||
struct lsDocumentCodeLensParams {
|
lsVersionedTextDocumentIdentifier textDocument;
|
||||||
lsTextDocumentIdentifier textDocument;
|
std::vector<lsTextDocumentContentChangeEvent> contentChanges;
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(lsDocumentCodeLensParams, textDocument);
|
MAKE_REFLECT_STRUCT(lsTextDocumentDidChangeParams,
|
||||||
struct lsCodeLensUserData {};
|
textDocument,
|
||||||
MAKE_REFLECT_EMPTY_STRUCT(lsCodeLensUserData);
|
contentChanges);
|
||||||
struct lsCodeLensCommandArguments {
|
|
||||||
lsDocumentUri uri;
|
|
||||||
lsPosition position;
|
|
||||||
NonElidedVector<lsLocation> locations;
|
|
||||||
};
|
|
||||||
void Reflect(Writer& visitor, lsCodeLensCommandArguments& value);
|
|
||||||
void Reflect(Reader& visitor, lsCodeLensCommandArguments& value);
|
|
||||||
using TCodeLens = lsCodeLens<lsCodeLensUserData, lsCodeLensCommandArguments>;
|
|
||||||
struct Ipc_TextDocumentCodeLens : public IpcMessage<Ipc_TextDocumentCodeLens> {
|
|
||||||
const static IpcId kIpcId = IpcId::TextDocumentCodeLens;
|
|
||||||
lsRequestId id;
|
|
||||||
lsDocumentCodeLensParams params;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_TextDocumentCodeLens, id, params);
|
|
||||||
struct Out_TextDocumentCodeLens
|
|
||||||
: public lsOutMessage<Out_TextDocumentCodeLens> {
|
|
||||||
lsRequestId id;
|
|
||||||
NonElidedVector<lsCodeLens<lsCodeLensUserData, lsCodeLensCommandArguments>>
|
|
||||||
result;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Out_TextDocumentCodeLens, jsonrpc, id, result);
|
|
||||||
struct Ipc_CodeLensResolve : public IpcMessage<Ipc_CodeLensResolve> {
|
|
||||||
const static IpcId kIpcId = IpcId::CodeLensResolve;
|
|
||||||
|
|
||||||
lsRequestId id;
|
|
||||||
TCodeLens params;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_CodeLensResolve, id, params);
|
|
||||||
struct Out_CodeLensResolve : public lsOutMessage<Out_CodeLensResolve> {
|
|
||||||
lsRequestId id;
|
|
||||||
TCodeLens result;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Out_CodeLensResolve, jsonrpc, id, result);
|
|
||||||
|
|
||||||
// Search for symbols in the workspace.
|
|
||||||
struct lsWorkspaceSymbolParams {
|
|
||||||
std::string query;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(lsWorkspaceSymbolParams, query);
|
|
||||||
struct Ipc_WorkspaceSymbol : public IpcMessage<Ipc_WorkspaceSymbol> {
|
|
||||||
const static IpcId kIpcId = IpcId::WorkspaceSymbol;
|
|
||||||
lsRequestId id;
|
|
||||||
lsWorkspaceSymbolParams params;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_WorkspaceSymbol, id, params);
|
|
||||||
struct Out_WorkspaceSymbol : public lsOutMessage<Out_WorkspaceSymbol> {
|
|
||||||
lsRequestId id;
|
|
||||||
NonElidedVector<lsSymbolInformation> result;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Out_WorkspaceSymbol, jsonrpc, id, result);
|
|
||||||
|
|
||||||
// Show a message to the user.
|
// Show a message to the user.
|
||||||
enum class lsMessageType : int { Error = 1, Warning = 2, Info = 3, Log = 4 };
|
enum class lsMessageType : int { Error = 1, Warning = 2, Info = 3, Log = 4 };
|
||||||
@ -1522,101 +1092,6 @@ MAKE_REFLECT_STRUCT(Out_CqueryPublishSemanticHighlighting,
|
|||||||
method,
|
method,
|
||||||
params);
|
params);
|
||||||
|
|
||||||
struct Ipc_CqueryFreshenIndex : public IpcMessage<Ipc_CqueryFreshenIndex> {
|
|
||||||
const static IpcId kIpcId = IpcId::CqueryFreshenIndex;
|
|
||||||
lsRequestId id;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_CqueryFreshenIndex, id);
|
|
||||||
|
|
||||||
// Type Hierarchy Tree
|
|
||||||
struct Ipc_CqueryTypeHierarchyTree
|
|
||||||
: public IpcMessage<Ipc_CqueryTypeHierarchyTree> {
|
|
||||||
const static IpcId kIpcId = IpcId::CqueryTypeHierarchyTree;
|
|
||||||
lsRequestId id;
|
|
||||||
lsTextDocumentPositionParams params;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_CqueryTypeHierarchyTree, id, params);
|
|
||||||
struct Out_CqueryTypeHierarchyTree
|
|
||||||
: public lsOutMessage<Out_CqueryTypeHierarchyTree> {
|
|
||||||
struct TypeEntry {
|
|
||||||
std::string name;
|
|
||||||
optional<lsLocation> location;
|
|
||||||
NonElidedVector<TypeEntry> children;
|
|
||||||
};
|
|
||||||
lsRequestId id;
|
|
||||||
optional<TypeEntry> result;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Out_CqueryTypeHierarchyTree::TypeEntry,
|
|
||||||
name,
|
|
||||||
location,
|
|
||||||
children);
|
|
||||||
MAKE_REFLECT_STRUCT(Out_CqueryTypeHierarchyTree, jsonrpc, id, result);
|
|
||||||
|
|
||||||
// Call Tree
|
|
||||||
struct Ipc_CqueryCallTreeInitial
|
|
||||||
: public IpcMessage<Ipc_CqueryCallTreeInitial> {
|
|
||||||
const static IpcId kIpcId = IpcId::CqueryCallTreeInitial;
|
|
||||||
lsRequestId id;
|
|
||||||
lsTextDocumentPositionParams params;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_CqueryCallTreeInitial, id, params);
|
|
||||||
struct Ipc_CqueryCallTreeExpand : public IpcMessage<Ipc_CqueryCallTreeExpand> {
|
|
||||||
struct Params {
|
|
||||||
std::string usr;
|
|
||||||
};
|
|
||||||
const static IpcId kIpcId = IpcId::CqueryCallTreeExpand;
|
|
||||||
lsRequestId id;
|
|
||||||
Params params;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_CqueryCallTreeExpand::Params, usr);
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_CqueryCallTreeExpand, id, params);
|
|
||||||
struct Out_CqueryCallTree : public lsOutMessage<Out_CqueryCallTree> {
|
|
||||||
enum class CallType { Direct = 0, Base = 1, Derived = 2 };
|
|
||||||
struct CallEntry {
|
|
||||||
std::string name;
|
|
||||||
std::string usr;
|
|
||||||
lsLocation location;
|
|
||||||
bool hasCallers = true;
|
|
||||||
CallType callType = CallType::Direct;
|
|
||||||
};
|
|
||||||
|
|
||||||
lsRequestId id;
|
|
||||||
NonElidedVector<CallEntry> result;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_TYPE_PROXY(Out_CqueryCallTree::CallType, int);
|
|
||||||
MAKE_REFLECT_STRUCT(Out_CqueryCallTree::CallEntry,
|
|
||||||
name,
|
|
||||||
usr,
|
|
||||||
location,
|
|
||||||
hasCallers,
|
|
||||||
callType);
|
|
||||||
MAKE_REFLECT_STRUCT(Out_CqueryCallTree, jsonrpc, id, result);
|
|
||||||
|
|
||||||
// Vars, Callers, Derived, GotoParent
|
|
||||||
struct Ipc_CqueryVars : public IpcMessage<Ipc_CqueryVars> {
|
|
||||||
const static IpcId kIpcId = IpcId::CqueryVars;
|
|
||||||
lsRequestId id;
|
|
||||||
lsTextDocumentPositionParams params;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_CqueryVars, id, params);
|
|
||||||
struct Ipc_CqueryCallers : public IpcMessage<Ipc_CqueryCallers> {
|
|
||||||
const static IpcId kIpcId = IpcId::CqueryCallers;
|
|
||||||
lsRequestId id;
|
|
||||||
lsTextDocumentPositionParams params;
|
|
||||||
};
|
|
||||||
struct Ipc_CqueryBase : public IpcMessage<Ipc_CqueryBase> {
|
|
||||||
const static IpcId kIpcId = IpcId::CqueryBase;
|
|
||||||
lsRequestId id;
|
|
||||||
lsTextDocumentPositionParams params;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_CqueryBase, id, params);
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_CqueryCallers, id, params);
|
|
||||||
struct Ipc_CqueryDerived : public IpcMessage<Ipc_CqueryDerived> {
|
|
||||||
const static IpcId kIpcId = IpcId::CqueryDerived;
|
|
||||||
lsRequestId id;
|
|
||||||
lsTextDocumentPositionParams params;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Ipc_CqueryDerived, id, params);
|
|
||||||
struct Out_LocationList : public lsOutMessage<Out_LocationList> {
|
struct Out_LocationList : public lsOutMessage<Out_LocationList> {
|
||||||
lsRequestId id;
|
lsRequestId id;
|
||||||
NonElidedVector<lsLocation> result;
|
NonElidedVector<lsLocation> result;
|
||||||
|
@ -146,73 +146,4 @@ void EmitSemanticHighlighting(QueryDatabase* db,
|
|||||||
for (auto& entry : grouped_symbols)
|
for (auto& entry : grouped_symbols)
|
||||||
out.params.symbols.push_back(entry.second);
|
out.params.symbols.push_back(entry.second);
|
||||||
IpcManager::WriteStdout(IpcId::CqueryPublishSemanticHighlighting, out);
|
IpcManager::WriteStdout(IpcId::CqueryPublishSemanticHighlighting, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FilterCompletionResponse(Out_TextDocumentComplete* complete_response,
|
|
||||||
const std::string& complete_text) {
|
|
||||||
// Used to inject more completions.
|
|
||||||
#if false
|
|
||||||
const size_t kNumIterations = 250;
|
|
||||||
size_t size = complete_response->result.items.size();
|
|
||||||
complete_response->result.items.reserve(size * (kNumIterations + 1));
|
|
||||||
for (size_t iteration = 0; iteration < kNumIterations; ++iteration) {
|
|
||||||
for (size_t i = 0; i < size; ++i) {
|
|
||||||
auto item = complete_response->result.items[i];
|
|
||||||
item.label += "#" + std::to_string(iteration);
|
|
||||||
complete_response->result.items.push_back(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const size_t kMaxResultSize = 100u;
|
|
||||||
if (complete_response->result.items.size() > kMaxResultSize) {
|
|
||||||
if (complete_text.empty()) {
|
|
||||||
complete_response->result.items.resize(kMaxResultSize);
|
|
||||||
} else {
|
|
||||||
NonElidedVector<lsCompletionItem> filtered_result;
|
|
||||||
filtered_result.reserve(kMaxResultSize);
|
|
||||||
|
|
||||||
std::unordered_set<std::string> inserted;
|
|
||||||
inserted.reserve(kMaxResultSize);
|
|
||||||
|
|
||||||
// Find literal matches first.
|
|
||||||
for (const lsCompletionItem& item : complete_response->result.items) {
|
|
||||||
if (item.label.find(complete_text) != std::string::npos) {
|
|
||||||
// Don't insert the same completion entry.
|
|
||||||
if (!inserted.insert(item.InsertedContent()).second)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
filtered_result.push_back(item);
|
|
||||||
if (filtered_result.size() >= kMaxResultSize)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find fuzzy matches if we haven't found all of the literal matches.
|
|
||||||
if (filtered_result.size() < kMaxResultSize) {
|
|
||||||
for (const lsCompletionItem& item : complete_response->result.items) {
|
|
||||||
if (SubstringMatch(complete_text, item.label)) {
|
|
||||||
// Don't insert the same completion entry.
|
|
||||||
if (!inserted.insert(item.InsertedContent()).second)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
filtered_result.push_back(item);
|
|
||||||
if (filtered_result.size() >= kMaxResultSize)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
complete_response->result.items = filtered_result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assuming the client does not support out-of-order completion (ie, ao
|
|
||||||
// matches against oa), our filtering is guaranteed to contain any
|
|
||||||
// potential matches, so the completion is only incomplete if we have the
|
|
||||||
// max number of emitted matches.
|
|
||||||
if (complete_response->result.items.size() >= kMaxResultSize) {
|
|
||||||
LOG_S(INFO) << "Marking completion results as incomplete";
|
|
||||||
complete_response->result.isIncomplete = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -77,10 +77,4 @@ void EmitInactiveLines(WorkingFile* working_file,
|
|||||||
void EmitSemanticHighlighting(QueryDatabase* db,
|
void EmitSemanticHighlighting(QueryDatabase* db,
|
||||||
SemanticHighlightSymbolCache* semantic_cache,
|
SemanticHighlightSymbolCache* semantic_cache,
|
||||||
WorkingFile* working_file,
|
WorkingFile* working_file,
|
||||||
QueryFile* file);
|
QueryFile* file);
|
||||||
|
|
||||||
// Pre-filters completion responses before sending to vscode. This results in a
|
|
||||||
// significantly snappier completion experience as vscode is easily overloaded
|
|
||||||
// when given 1000+ completion items.
|
|
||||||
void FilterCompletionResponse(Out_TextDocumentComplete* complete_response,
|
|
||||||
const std::string& complete_text);
|
|
@ -1,6 +1,14 @@
|
|||||||
#include "message_handler.h"
|
#include "message_handler.h"
|
||||||
#include "query_utils.h"
|
#include "query_utils.h"
|
||||||
|
|
||||||
|
struct Ipc_CqueryBase : public IpcMessage<Ipc_CqueryBase> {
|
||||||
|
const static IpcId kIpcId = IpcId::CqueryBase;
|
||||||
|
lsRequestId id;
|
||||||
|
lsTextDocumentPositionParams params;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_CqueryBase, id, params);
|
||||||
|
REGISTER_IPC_MESSAGE(Ipc_CqueryBase);
|
||||||
|
|
||||||
struct CqueryBaseHandler : BaseMessageHandler<Ipc_CqueryBase> {
|
struct CqueryBaseHandler : BaseMessageHandler<Ipc_CqueryBase> {
|
||||||
void Run(Ipc_CqueryBase* request) override {
|
void Run(Ipc_CqueryBase* request) override {
|
||||||
QueryFile* file;
|
QueryFile* file;
|
||||||
|
@ -1,6 +1,177 @@
|
|||||||
#include "message_handler.h"
|
#include "message_handler.h"
|
||||||
#include "query_utils.h"
|
#include "query_utils.h"
|
||||||
|
|
||||||
|
struct Ipc_CqueryCallTreeInitial
|
||||||
|
: public IpcMessage<Ipc_CqueryCallTreeInitial> {
|
||||||
|
const static IpcId kIpcId = IpcId::CqueryCallTreeInitial;
|
||||||
|
lsRequestId id;
|
||||||
|
lsTextDocumentPositionParams params;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_CqueryCallTreeInitial, id, params);
|
||||||
|
REGISTER_IPC_MESSAGE(Ipc_CqueryCallTreeInitial);
|
||||||
|
|
||||||
|
struct Ipc_CqueryCallTreeExpand : public IpcMessage<Ipc_CqueryCallTreeExpand> {
|
||||||
|
struct Params {
|
||||||
|
std::string usr;
|
||||||
|
};
|
||||||
|
const static IpcId kIpcId = IpcId::CqueryCallTreeExpand;
|
||||||
|
lsRequestId id;
|
||||||
|
Params params;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_CqueryCallTreeExpand::Params, usr);
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_CqueryCallTreeExpand, id, params);
|
||||||
|
REGISTER_IPC_MESSAGE(Ipc_CqueryCallTreeExpand);
|
||||||
|
|
||||||
|
struct Out_CqueryCallTree : public lsOutMessage<Out_CqueryCallTree> {
|
||||||
|
enum class CallType { Direct = 0, Base = 1, Derived = 2 };
|
||||||
|
struct CallEntry {
|
||||||
|
std::string name;
|
||||||
|
std::string usr;
|
||||||
|
lsLocation location;
|
||||||
|
bool hasCallers = true;
|
||||||
|
CallType callType = CallType::Direct;
|
||||||
|
};
|
||||||
|
|
||||||
|
lsRequestId id;
|
||||||
|
NonElidedVector<CallEntry> result;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_TYPE_PROXY(Out_CqueryCallTree::CallType, int);
|
||||||
|
MAKE_REFLECT_STRUCT(Out_CqueryCallTree::CallEntry,
|
||||||
|
name,
|
||||||
|
usr,
|
||||||
|
location,
|
||||||
|
hasCallers,
|
||||||
|
callType);
|
||||||
|
MAKE_REFLECT_STRUCT(Out_CqueryCallTree, jsonrpc, id, result);
|
||||||
|
|
||||||
|
NonElidedVector<Out_CqueryCallTree::CallEntry> BuildInitialCallTree(
|
||||||
|
QueryDatabase* db,
|
||||||
|
WorkingFiles* working_files,
|
||||||
|
QueryFuncId root) {
|
||||||
|
QueryFunc& root_func = db->funcs[root.id];
|
||||||
|
if (!root_func.def || !root_func.def->definition_spelling)
|
||||||
|
return {};
|
||||||
|
optional<lsLocation> def_loc =
|
||||||
|
GetLsLocation(db, working_files, *root_func.def->definition_spelling);
|
||||||
|
if (!def_loc)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
Out_CqueryCallTree::CallEntry entry;
|
||||||
|
entry.name = root_func.def->short_name;
|
||||||
|
entry.usr = root_func.def->usr;
|
||||||
|
entry.location = *def_loc;
|
||||||
|
entry.hasCallers = HasCallersOnSelfOrBaseOrDerived(db, root_func);
|
||||||
|
NonElidedVector<Out_CqueryCallTree::CallEntry> result;
|
||||||
|
result.push_back(entry);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
NonElidedVector<Out_CqueryCallTree::CallEntry> BuildExpandCallTree(
|
||||||
|
QueryDatabase* db,
|
||||||
|
WorkingFiles* working_files,
|
||||||
|
QueryFuncId root) {
|
||||||
|
QueryFunc& root_func = db->funcs[root.id];
|
||||||
|
if (!root_func.def)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
auto format_location =
|
||||||
|
[&](const lsLocation& location,
|
||||||
|
optional<QueryTypeId> declaring_type) -> std::string {
|
||||||
|
std::string base;
|
||||||
|
|
||||||
|
if (declaring_type) {
|
||||||
|
QueryType type = db->types[declaring_type->id];
|
||||||
|
if (type.def)
|
||||||
|
base = type.def->detailed_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (base.empty()) {
|
||||||
|
base = location.uri.GetPath();
|
||||||
|
size_t last_index = base.find_last_of('/');
|
||||||
|
if (last_index != std::string::npos)
|
||||||
|
base = base.substr(last_index + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return base + ":" + std::to_string(location.range.start.line + 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
NonElidedVector<Out_CqueryCallTree::CallEntry> result;
|
||||||
|
std::unordered_set<QueryLocation> seen_locations;
|
||||||
|
|
||||||
|
auto handle_caller = [&](QueryFuncRef caller,
|
||||||
|
Out_CqueryCallTree::CallType call_type) {
|
||||||
|
optional<lsLocation> call_location =
|
||||||
|
GetLsLocation(db, working_files, caller.loc);
|
||||||
|
if (!call_location)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// TODO: REMOVE |seen_locations| once we fix the querydb update bugs
|
||||||
|
// TODO: REMOVE |seen_locations| once we fix the querydb update bugs
|
||||||
|
// TODO: REMOVE |seen_locations| once we fix the querydb update bugs
|
||||||
|
// TODO: REMOVE |seen_locations| once we fix the querydb update bugs
|
||||||
|
// TODO: REMOVE |seen_locations| once we fix the querydb update bugs
|
||||||
|
// TODO: REMOVE |seen_locations| once we fix the querydb update bugs
|
||||||
|
// TODO: REMOVE |seen_locations| once we fix the querydb update bugs
|
||||||
|
// TODO: REMOVE |seen_locations| once we fix the querydb update bugs
|
||||||
|
// TODO: REMOVE |seen_locations| once we fix the querydb update bugs
|
||||||
|
// TODO: REMOVE |seen_locations| once we fix the querydb update bugs
|
||||||
|
// TODO: REMOVE |seen_locations| once we fix the querydb update bugs
|
||||||
|
// TODO: REMOVE |seen_locations| once we fix the querydb update bugs
|
||||||
|
// TODO: basically, querydb gets duplicate references inserted into it.
|
||||||
|
if (!seen_locations.insert(caller.loc).second) {
|
||||||
|
std::cerr << "!!!! FIXME DUPLICATE REFERENCE IN QUERYDB" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (caller.has_id()) {
|
||||||
|
QueryFunc& call_func = db->funcs[caller.id_.id];
|
||||||
|
if (!call_func.def)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Out_CqueryCallTree::CallEntry call_entry;
|
||||||
|
call_entry.name =
|
||||||
|
call_func.def->short_name + " (" +
|
||||||
|
format_location(*call_location, call_func.def->declaring_type) + ")";
|
||||||
|
call_entry.usr = call_func.def->usr;
|
||||||
|
call_entry.location = *call_location;
|
||||||
|
call_entry.hasCallers = HasCallersOnSelfOrBaseOrDerived(db, call_func);
|
||||||
|
call_entry.callType = call_type;
|
||||||
|
result.push_back(call_entry);
|
||||||
|
} else {
|
||||||
|
// TODO: See if we can do a better job here. Need more information from
|
||||||
|
// the indexer.
|
||||||
|
Out_CqueryCallTree::CallEntry call_entry;
|
||||||
|
call_entry.name = "Likely Constructor";
|
||||||
|
call_entry.usr = "no_usr";
|
||||||
|
call_entry.location = *call_location;
|
||||||
|
call_entry.hasCallers = false;
|
||||||
|
call_entry.callType = call_type;
|
||||||
|
result.push_back(call_entry);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<QueryFuncRef> base_callers =
|
||||||
|
GetCallersForAllBaseFunctions(db, root_func);
|
||||||
|
std::vector<QueryFuncRef> derived_callers =
|
||||||
|
GetCallersForAllDerivedFunctions(db, root_func);
|
||||||
|
result.reserve(root_func.callers.size() + base_callers.size() +
|
||||||
|
derived_callers.size());
|
||||||
|
|
||||||
|
for (QueryFuncRef caller : root_func.callers)
|
||||||
|
handle_caller(caller, Out_CqueryCallTree::CallType::Direct);
|
||||||
|
for (QueryFuncRef caller : base_callers) {
|
||||||
|
// Do not show calls to the base function coming from this function.
|
||||||
|
if (caller.id_ == root)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
handle_caller(caller, Out_CqueryCallTree::CallType::Base);
|
||||||
|
}
|
||||||
|
for (QueryFuncRef caller : derived_callers)
|
||||||
|
handle_caller(caller, Out_CqueryCallTree::CallType::Derived);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
struct CqueryCallTreeInitialHandler
|
struct CqueryCallTreeInitialHandler
|
||||||
: BaseMessageHandler<Ipc_CqueryCallTreeInitial> {
|
: BaseMessageHandler<Ipc_CqueryCallTreeInitial> {
|
||||||
void Run(Ipc_CqueryCallTreeInitial* request) override {
|
void Run(Ipc_CqueryCallTreeInitial* request) override {
|
||||||
|
@ -1,6 +1,14 @@
|
|||||||
#include "message_handler.h"
|
#include "message_handler.h"
|
||||||
#include "query_utils.h"
|
#include "query_utils.h"
|
||||||
|
|
||||||
|
struct Ipc_CqueryCallers : public IpcMessage<Ipc_CqueryCallers> {
|
||||||
|
const static IpcId kIpcId = IpcId::CqueryCallers;
|
||||||
|
lsRequestId id;
|
||||||
|
lsTextDocumentPositionParams params;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_CqueryCallers, id, params);
|
||||||
|
REGISTER_IPC_MESSAGE(Ipc_CqueryCallers);
|
||||||
|
|
||||||
struct CqueryCallersHandler : BaseMessageHandler<Ipc_CqueryCallers> {
|
struct CqueryCallersHandler : BaseMessageHandler<Ipc_CqueryCallers> {
|
||||||
void Run(Ipc_CqueryCallers* request) override {
|
void Run(Ipc_CqueryCallers* request) override {
|
||||||
QueryFile* file;
|
QueryFile* file;
|
||||||
|
@ -1,6 +1,14 @@
|
|||||||
#include "message_handler.h"
|
#include "message_handler.h"
|
||||||
#include "query_utils.h"
|
#include "query_utils.h"
|
||||||
|
|
||||||
|
struct Ipc_CqueryDerived : public IpcMessage<Ipc_CqueryDerived> {
|
||||||
|
const static IpcId kIpcId = IpcId::CqueryDerived;
|
||||||
|
lsRequestId id;
|
||||||
|
lsTextDocumentPositionParams params;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_CqueryDerived, id, params);
|
||||||
|
REGISTER_IPC_MESSAGE(Ipc_CqueryDerived);
|
||||||
|
|
||||||
struct CqueryDerivedHandler : BaseMessageHandler<Ipc_CqueryDerived> {
|
struct CqueryDerivedHandler : BaseMessageHandler<Ipc_CqueryDerived> {
|
||||||
void Run(Ipc_CqueryDerived* request) override {
|
void Run(Ipc_CqueryDerived* request) override {
|
||||||
QueryFile* file;
|
QueryFile* file;
|
||||||
|
@ -1,5 +1,18 @@
|
|||||||
#include "message_handler.h"
|
#include "message_handler.h"
|
||||||
|
|
||||||
|
struct Ipc_CqueryTextDocumentDidView
|
||||||
|
: public IpcMessage<Ipc_CqueryTextDocumentDidView> {
|
||||||
|
struct Params {
|
||||||
|
lsDocumentUri textDocumentUri;
|
||||||
|
};
|
||||||
|
|
||||||
|
const static IpcId kIpcId = IpcId::CqueryTextDocumentDidView;
|
||||||
|
Params params;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_CqueryTextDocumentDidView::Params, textDocumentUri);
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_CqueryTextDocumentDidView, params);
|
||||||
|
REGISTER_IPC_MESSAGE(Ipc_CqueryTextDocumentDidView);
|
||||||
|
|
||||||
struct CqueryDidViewHandler
|
struct CqueryDidViewHandler
|
||||||
: BaseMessageHandler<Ipc_CqueryTextDocumentDidView> {
|
: BaseMessageHandler<Ipc_CqueryTextDocumentDidView> {
|
||||||
void Run(Ipc_CqueryTextDocumentDidView* request) override {
|
void Run(Ipc_CqueryTextDocumentDidView* request) override {
|
||||||
|
@ -3,6 +3,12 @@
|
|||||||
|
|
||||||
#include <loguru.hpp>
|
#include <loguru.hpp>
|
||||||
|
|
||||||
|
struct Ipc_CqueryExitWhenIdle : public IpcMessage<Ipc_CqueryExitWhenIdle> {
|
||||||
|
static constexpr IpcId kIpcId = IpcId::CqueryExitWhenIdle;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_EMPTY_STRUCT(Ipc_CqueryExitWhenIdle);
|
||||||
|
REGISTER_IPC_MESSAGE(Ipc_CqueryExitWhenIdle);
|
||||||
|
|
||||||
struct CqueryExitWhenIdleHandler : MessageHandler {
|
struct CqueryExitWhenIdleHandler : MessageHandler {
|
||||||
IpcId GetId() const override { return IpcId::CqueryExitWhenIdle; }
|
IpcId GetId() const override { return IpcId::CqueryExitWhenIdle; }
|
||||||
void Run(std::unique_ptr<BaseIpcMessage> request) override {
|
void Run(std::unique_ptr<BaseIpcMessage> request) override {
|
||||||
|
@ -3,6 +3,13 @@
|
|||||||
|
|
||||||
#include <loguru.hpp>
|
#include <loguru.hpp>
|
||||||
|
|
||||||
|
struct Ipc_CqueryFreshenIndex : public IpcMessage<Ipc_CqueryFreshenIndex> {
|
||||||
|
const static IpcId kIpcId = IpcId::CqueryFreshenIndex;
|
||||||
|
lsRequestId id;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_CqueryFreshenIndex, id);
|
||||||
|
REGISTER_IPC_MESSAGE(Ipc_CqueryFreshenIndex);
|
||||||
|
|
||||||
struct CqueryFreshenIndexHandler : MessageHandler {
|
struct CqueryFreshenIndexHandler : MessageHandler {
|
||||||
IpcId GetId() const override { return IpcId::CqueryFreshenIndex; }
|
IpcId GetId() const override { return IpcId::CqueryFreshenIndex; }
|
||||||
|
|
||||||
|
@ -1,6 +1,25 @@
|
|||||||
#include "message_handler.h"
|
#include "message_handler.h"
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
|
|
||||||
|
struct Ipc_CqueryIndexFile : public IpcMessage<Ipc_CqueryIndexFile> {
|
||||||
|
static constexpr IpcId kIpcId = IpcId::CqueryIndexFile;
|
||||||
|
|
||||||
|
struct Params {
|
||||||
|
std::string path;
|
||||||
|
std::vector<std::string> args;
|
||||||
|
bool is_interactive = false;
|
||||||
|
std::string contents;
|
||||||
|
};
|
||||||
|
Params params;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_CqueryIndexFile::Params,
|
||||||
|
path,
|
||||||
|
args,
|
||||||
|
is_interactive,
|
||||||
|
contents);
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_CqueryIndexFile, params);
|
||||||
|
REGISTER_IPC_MESSAGE(Ipc_CqueryIndexFile);
|
||||||
|
|
||||||
struct CqueryIndexFileHandler : BaseMessageHandler<Ipc_CqueryIndexFile> {
|
struct CqueryIndexFileHandler : BaseMessageHandler<Ipc_CqueryIndexFile> {
|
||||||
void Run(Ipc_CqueryIndexFile* request) override {
|
void Run(Ipc_CqueryIndexFile* request) override {
|
||||||
queue->index_request.Enqueue(Index_Request(
|
queue->index_request.Enqueue(Index_Request(
|
||||||
|
@ -3,6 +3,13 @@
|
|||||||
|
|
||||||
#include <loguru.hpp>
|
#include <loguru.hpp>
|
||||||
|
|
||||||
|
struct Ipc_CqueryQueryDbWaitForIdleIndexer
|
||||||
|
: public IpcMessage<Ipc_CqueryQueryDbWaitForIdleIndexer> {
|
||||||
|
static constexpr IpcId kIpcId = IpcId::CqueryQueryDbWaitForIdleIndexer;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_EMPTY_STRUCT(Ipc_CqueryQueryDbWaitForIdleIndexer);
|
||||||
|
REGISTER_IPC_MESSAGE(Ipc_CqueryQueryDbWaitForIdleIndexer);
|
||||||
|
|
||||||
struct CqueryQueryDbWaitForIdleIndexerHandler : MessageHandler {
|
struct CqueryQueryDbWaitForIdleIndexerHandler : MessageHandler {
|
||||||
IpcId GetId() const override {
|
IpcId GetId() const override {
|
||||||
return IpcId::CqueryQueryDbWaitForIdleIndexer;
|
return IpcId::CqueryQueryDbWaitForIdleIndexer;
|
||||||
|
@ -1,6 +1,162 @@
|
|||||||
#include "message_handler.h"
|
#include "message_handler.h"
|
||||||
#include "query_utils.h"
|
#include "query_utils.h"
|
||||||
|
|
||||||
|
struct Ipc_CqueryTypeHierarchyTree
|
||||||
|
: public IpcMessage<Ipc_CqueryTypeHierarchyTree> {
|
||||||
|
const static IpcId kIpcId = IpcId::CqueryTypeHierarchyTree;
|
||||||
|
lsRequestId id;
|
||||||
|
lsTextDocumentPositionParams params;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_CqueryTypeHierarchyTree, id, params);
|
||||||
|
REGISTER_IPC_MESSAGE(Ipc_CqueryTypeHierarchyTree);
|
||||||
|
|
||||||
|
struct Out_CqueryTypeHierarchyTree
|
||||||
|
: public lsOutMessage<Out_CqueryTypeHierarchyTree> {
|
||||||
|
struct TypeEntry {
|
||||||
|
std::string name;
|
||||||
|
optional<lsLocation> location;
|
||||||
|
NonElidedVector<TypeEntry> children;
|
||||||
|
};
|
||||||
|
lsRequestId id;
|
||||||
|
optional<TypeEntry> result;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Out_CqueryTypeHierarchyTree::TypeEntry,
|
||||||
|
name,
|
||||||
|
location,
|
||||||
|
children);
|
||||||
|
MAKE_REFLECT_STRUCT(Out_CqueryTypeHierarchyTree, jsonrpc, id, result);
|
||||||
|
|
||||||
|
NonElidedVector<Out_CqueryTypeHierarchyTree::TypeEntry>
|
||||||
|
BuildParentInheritanceHierarchyForType(QueryDatabase* db,
|
||||||
|
WorkingFiles* working_files,
|
||||||
|
QueryTypeId root) {
|
||||||
|
QueryType& root_type = db->types[root.id];
|
||||||
|
if (!root_type.def)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
NonElidedVector<Out_CqueryTypeHierarchyTree::TypeEntry> parent_entries;
|
||||||
|
parent_entries.reserve(root_type.def->parents.size());
|
||||||
|
|
||||||
|
for (QueryTypeId parent_id : root_type.def->parents) {
|
||||||
|
QueryType& parent_type = db->types[parent_id.id];
|
||||||
|
if (!parent_type.def)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Out_CqueryTypeHierarchyTree::TypeEntry parent_entry;
|
||||||
|
parent_entry.name = parent_type.def->detailed_name;
|
||||||
|
if (parent_type.def->definition_spelling)
|
||||||
|
parent_entry.location = GetLsLocation(
|
||||||
|
db, working_files, *parent_type.def->definition_spelling);
|
||||||
|
parent_entry.children =
|
||||||
|
BuildParentInheritanceHierarchyForType(db, working_files, parent_id);
|
||||||
|
|
||||||
|
parent_entries.push_back(parent_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
optional<Out_CqueryTypeHierarchyTree::TypeEntry>
|
||||||
|
BuildInheritanceHierarchyForType(QueryDatabase* db,
|
||||||
|
WorkingFiles* working_files,
|
||||||
|
QueryTypeId root_id) {
|
||||||
|
QueryType& root_type = db->types[root_id.id];
|
||||||
|
if (!root_type.def)
|
||||||
|
return nullopt;
|
||||||
|
|
||||||
|
Out_CqueryTypeHierarchyTree::TypeEntry entry;
|
||||||
|
|
||||||
|
// Name and location.
|
||||||
|
entry.name = root_type.def->detailed_name;
|
||||||
|
if (root_type.def->definition_spelling)
|
||||||
|
entry.location =
|
||||||
|
GetLsLocation(db, working_files, *root_type.def->definition_spelling);
|
||||||
|
|
||||||
|
entry.children.reserve(root_type.derived.size());
|
||||||
|
|
||||||
|
// Base types.
|
||||||
|
Out_CqueryTypeHierarchyTree::TypeEntry base;
|
||||||
|
base.name = "[[Base]]";
|
||||||
|
base.location = entry.location;
|
||||||
|
base.children =
|
||||||
|
BuildParentInheritanceHierarchyForType(db, working_files, root_id);
|
||||||
|
if (!base.children.empty())
|
||||||
|
entry.children.push_back(base);
|
||||||
|
|
||||||
|
// Add derived.
|
||||||
|
for (QueryTypeId derived : root_type.derived) {
|
||||||
|
auto derived_entry =
|
||||||
|
BuildInheritanceHierarchyForType(db, working_files, derived);
|
||||||
|
if (derived_entry)
|
||||||
|
entry.children.push_back(*derived_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
NonElidedVector<Out_CqueryTypeHierarchyTree::TypeEntry>
|
||||||
|
BuildParentInheritanceHierarchyForFunc(QueryDatabase* db,
|
||||||
|
WorkingFiles* working_files,
|
||||||
|
QueryFuncId root) {
|
||||||
|
QueryFunc& root_func = db->funcs[root.id];
|
||||||
|
if (!root_func.def || !root_func.def->base)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
QueryFunc& parent_func = db->funcs[root_func.def->base->id];
|
||||||
|
if (!parent_func.def)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
Out_CqueryTypeHierarchyTree::TypeEntry parent_entry;
|
||||||
|
parent_entry.name = parent_func.def->detailed_name;
|
||||||
|
if (parent_func.def->definition_spelling)
|
||||||
|
parent_entry.location =
|
||||||
|
GetLsLocation(db, working_files, *parent_func.def->definition_spelling);
|
||||||
|
parent_entry.children = BuildParentInheritanceHierarchyForFunc(
|
||||||
|
db, working_files, *root_func.def->base);
|
||||||
|
|
||||||
|
NonElidedVector<Out_CqueryTypeHierarchyTree::TypeEntry> entries;
|
||||||
|
entries.push_back(parent_entry);
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
optional<Out_CqueryTypeHierarchyTree::TypeEntry>
|
||||||
|
BuildInheritanceHierarchyForFunc(QueryDatabase* db,
|
||||||
|
WorkingFiles* working_files,
|
||||||
|
QueryFuncId root_id) {
|
||||||
|
QueryFunc& root_func = db->funcs[root_id.id];
|
||||||
|
if (!root_func.def)
|
||||||
|
return nullopt;
|
||||||
|
|
||||||
|
Out_CqueryTypeHierarchyTree::TypeEntry entry;
|
||||||
|
|
||||||
|
// Name and location.
|
||||||
|
entry.name = root_func.def->detailed_name;
|
||||||
|
if (root_func.def->definition_spelling)
|
||||||
|
entry.location =
|
||||||
|
GetLsLocation(db, working_files, *root_func.def->definition_spelling);
|
||||||
|
|
||||||
|
entry.children.reserve(root_func.derived.size());
|
||||||
|
|
||||||
|
// Base types.
|
||||||
|
Out_CqueryTypeHierarchyTree::TypeEntry base;
|
||||||
|
base.name = "[[Base]]";
|
||||||
|
base.location = entry.location;
|
||||||
|
base.children =
|
||||||
|
BuildParentInheritanceHierarchyForFunc(db, working_files, root_id);
|
||||||
|
if (!base.children.empty())
|
||||||
|
entry.children.push_back(base);
|
||||||
|
|
||||||
|
// Add derived.
|
||||||
|
for (QueryFuncId derived : root_func.derived) {
|
||||||
|
auto derived_entry =
|
||||||
|
BuildInheritanceHierarchyForFunc(db, working_files, derived);
|
||||||
|
if (derived_entry)
|
||||||
|
entry.children.push_back(*derived_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
struct CqueryTypeHierarchyTreeHandler
|
struct CqueryTypeHierarchyTreeHandler
|
||||||
: BaseMessageHandler<Ipc_CqueryTypeHierarchyTree> {
|
: BaseMessageHandler<Ipc_CqueryTypeHierarchyTree> {
|
||||||
void Run(Ipc_CqueryTypeHierarchyTree* request) override {
|
void Run(Ipc_CqueryTypeHierarchyTree* request) override {
|
||||||
|
@ -1,6 +1,14 @@
|
|||||||
#include "message_handler.h"
|
#include "message_handler.h"
|
||||||
#include "query_utils.h"
|
#include "query_utils.h"
|
||||||
|
|
||||||
|
struct Ipc_CqueryVars : public IpcMessage<Ipc_CqueryVars> {
|
||||||
|
const static IpcId kIpcId = IpcId::CqueryVars;
|
||||||
|
lsRequestId id;
|
||||||
|
lsTextDocumentPositionParams params;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_CqueryVars, id, params);
|
||||||
|
REGISTER_IPC_MESSAGE(Ipc_CqueryVars);
|
||||||
|
|
||||||
struct CqueryVarsHandler : BaseMessageHandler<Ipc_CqueryVars> {
|
struct CqueryVarsHandler : BaseMessageHandler<Ipc_CqueryVars> {
|
||||||
void Run(Ipc_CqueryVars* request) override {
|
void Run(Ipc_CqueryVars* request) override {
|
||||||
QueryFile* file;
|
QueryFile* file;
|
||||||
|
@ -2,6 +2,12 @@
|
|||||||
|
|
||||||
#include <loguru.hpp>
|
#include <loguru.hpp>
|
||||||
|
|
||||||
|
struct Ipc_Exit : public IpcMessage<Ipc_Exit> {
|
||||||
|
static const IpcId kIpcId = IpcId::Exit;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_EMPTY_STRUCT(Ipc_Exit);
|
||||||
|
REGISTER_IPC_MESSAGE(Ipc_Exit);
|
||||||
|
|
||||||
struct ExitHandler : MessageHandler {
|
struct ExitHandler : MessageHandler {
|
||||||
IpcId GetId() const override { return IpcId::Exit; }
|
IpcId GetId() const override { return IpcId::Exit; }
|
||||||
|
|
||||||
|
@ -2,8 +2,9 @@
|
|||||||
#include "message_handler.h"
|
#include "message_handler.h"
|
||||||
#include "query_utils.h"
|
#include "query_utils.h"
|
||||||
|
|
||||||
#include <climits>
|
|
||||||
#include <doctest/doctest.h>
|
#include <doctest/doctest.h>
|
||||||
|
|
||||||
|
#include <climits>
|
||||||
#include <loguru.hpp>
|
#include <loguru.hpp>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -248,6 +249,53 @@ optional<lsTextEdit> BuildAutoImplementForFunction(QueryDatabase* db,
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
struct Ipc_TextDocumentCodeAction
|
||||||
|
: public IpcMessage<Ipc_TextDocumentCodeAction> {
|
||||||
|
const static IpcId kIpcId = IpcId::TextDocumentCodeAction;
|
||||||
|
// Contains additional diagnostic information about the context in which
|
||||||
|
// a code action is run.
|
||||||
|
struct lsCodeActionContext {
|
||||||
|
// An array of diagnostics.
|
||||||
|
NonElidedVector<lsDiagnostic> diagnostics;
|
||||||
|
};
|
||||||
|
// Params for the CodeActionRequest
|
||||||
|
struct lsCodeActionParams {
|
||||||
|
// The document in which the command was invoked.
|
||||||
|
lsTextDocumentIdentifier textDocument;
|
||||||
|
// The range for which the command was invoked.
|
||||||
|
lsRange range;
|
||||||
|
// Context carrying additional information.
|
||||||
|
lsCodeActionContext context;
|
||||||
|
};
|
||||||
|
|
||||||
|
lsRequestId id;
|
||||||
|
lsCodeActionParams params;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_TextDocumentCodeAction::lsCodeActionContext,
|
||||||
|
diagnostics);
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_TextDocumentCodeAction::lsCodeActionParams,
|
||||||
|
textDocument,
|
||||||
|
range,
|
||||||
|
context);
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_TextDocumentCodeAction, id, params);
|
||||||
|
REGISTER_IPC_MESSAGE(Ipc_TextDocumentCodeAction);
|
||||||
|
|
||||||
|
struct Out_TextDocumentCodeAction
|
||||||
|
: public lsOutMessage<Out_TextDocumentCodeAction> {
|
||||||
|
struct CommandArgs {
|
||||||
|
lsDocumentUri textDocumentUri;
|
||||||
|
NonElidedVector<lsTextEdit> edits;
|
||||||
|
};
|
||||||
|
using Command = lsCommand<CommandArgs>;
|
||||||
|
|
||||||
|
lsRequestId id;
|
||||||
|
NonElidedVector<Command> result;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT_WRITER_AS_ARRAY(Out_TextDocumentCodeAction::CommandArgs,
|
||||||
|
textDocumentUri,
|
||||||
|
edits);
|
||||||
|
MAKE_REFLECT_STRUCT(Out_TextDocumentCodeAction, jsonrpc, id, result);
|
||||||
|
|
||||||
struct TextDocumentCodeActionHandler
|
struct TextDocumentCodeActionHandler
|
||||||
: BaseMessageHandler<Ipc_TextDocumentCodeAction> {
|
: BaseMessageHandler<Ipc_TextDocumentCodeAction> {
|
||||||
void Run(Ipc_TextDocumentCodeAction* request) override {
|
void Run(Ipc_TextDocumentCodeAction* request) override {
|
||||||
|
@ -1,6 +1,119 @@
|
|||||||
#include "message_handler.h"
|
#include "message_handler.h"
|
||||||
#include "query_utils.h"
|
#include "query_utils.h"
|
||||||
|
|
||||||
|
struct lsDocumentCodeLensParams {
|
||||||
|
lsTextDocumentIdentifier textDocument;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(lsDocumentCodeLensParams, textDocument);
|
||||||
|
|
||||||
|
struct lsCodeLensUserData {};
|
||||||
|
MAKE_REFLECT_EMPTY_STRUCT(lsCodeLensUserData);
|
||||||
|
|
||||||
|
struct lsCodeLensCommandArguments {
|
||||||
|
lsDocumentUri uri;
|
||||||
|
lsPosition position;
|
||||||
|
NonElidedVector<lsLocation> locations;
|
||||||
|
};
|
||||||
|
void Reflect(Writer& visitor, lsCodeLensCommandArguments& value) {
|
||||||
|
visitor.StartArray();
|
||||||
|
Reflect(visitor, value.uri);
|
||||||
|
Reflect(visitor, value.position);
|
||||||
|
Reflect(visitor, value.locations);
|
||||||
|
visitor.EndArray();
|
||||||
|
}
|
||||||
|
void Reflect(Reader& visitor, lsCodeLensCommandArguments& value) {
|
||||||
|
auto it = visitor.Begin();
|
||||||
|
Reflect(*it, value.uri);
|
||||||
|
++it;
|
||||||
|
Reflect(*it, value.position);
|
||||||
|
++it;
|
||||||
|
Reflect(*it, value.locations);
|
||||||
|
}
|
||||||
|
|
||||||
|
using TCodeLens = lsCodeLens<lsCodeLensUserData, lsCodeLensCommandArguments>;
|
||||||
|
struct Ipc_TextDocumentCodeLens : public IpcMessage<Ipc_TextDocumentCodeLens> {
|
||||||
|
const static IpcId kIpcId = IpcId::TextDocumentCodeLens;
|
||||||
|
lsRequestId id;
|
||||||
|
lsDocumentCodeLensParams params;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_TextDocumentCodeLens, id, params);
|
||||||
|
REGISTER_IPC_MESSAGE(Ipc_TextDocumentCodeLens);
|
||||||
|
|
||||||
|
struct Out_TextDocumentCodeLens
|
||||||
|
: public lsOutMessage<Out_TextDocumentCodeLens> {
|
||||||
|
lsRequestId id;
|
||||||
|
NonElidedVector<lsCodeLens<lsCodeLensUserData, lsCodeLensCommandArguments>>
|
||||||
|
result;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Out_TextDocumentCodeLens, jsonrpc, id, result);
|
||||||
|
|
||||||
|
#if false
|
||||||
|
struct Ipc_CodeLensResolve : public IpcMessage<Ipc_CodeLensResolve> {
|
||||||
|
const static IpcId kIpcId = IpcId::CodeLensResolve;
|
||||||
|
|
||||||
|
lsRequestId id;
|
||||||
|
TCodeLens params;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_CodeLensResolve, id, params);
|
||||||
|
REGISTER_IPC_MESSAGE(Ipc_CodeLensResolve);
|
||||||
|
|
||||||
|
struct Out_CodeLensResolve : public lsOutMessage<Out_CodeLensResolve> {
|
||||||
|
lsRequestId id;
|
||||||
|
TCodeLens result;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Out_CodeLensResolve, jsonrpc, id, result);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct CommonCodeLensParams {
|
||||||
|
std::vector<TCodeLens>* result;
|
||||||
|
QueryDatabase* db;
|
||||||
|
WorkingFiles* working_files;
|
||||||
|
WorkingFile* working_file;
|
||||||
|
};
|
||||||
|
|
||||||
|
void AddCodeLens(const char* singular,
|
||||||
|
const char* plural,
|
||||||
|
CommonCodeLensParams* common,
|
||||||
|
QueryLocation loc,
|
||||||
|
const std::vector<QueryLocation>& uses,
|
||||||
|
optional<QueryLocation> excluded,
|
||||||
|
bool force_display) {
|
||||||
|
TCodeLens code_lens;
|
||||||
|
optional<lsRange> range = GetLsRange(common->working_file, loc.range);
|
||||||
|
if (!range)
|
||||||
|
return;
|
||||||
|
code_lens.range = *range;
|
||||||
|
code_lens.command = lsCommand<lsCodeLensCommandArguments>();
|
||||||
|
code_lens.command->command = "cquery.showReferences";
|
||||||
|
code_lens.command->arguments.uri = GetLsDocumentUri(common->db, loc.path);
|
||||||
|
code_lens.command->arguments.position = code_lens.range.start;
|
||||||
|
|
||||||
|
// Add unique uses.
|
||||||
|
std::unordered_set<lsLocation> unique_uses;
|
||||||
|
for (const QueryLocation& use : uses) {
|
||||||
|
if (excluded == use)
|
||||||
|
continue;
|
||||||
|
optional<lsLocation> location =
|
||||||
|
GetLsLocation(common->db, common->working_files, use);
|
||||||
|
if (!location)
|
||||||
|
continue;
|
||||||
|
unique_uses.insert(*location);
|
||||||
|
}
|
||||||
|
code_lens.command->arguments.locations.assign(unique_uses.begin(),
|
||||||
|
unique_uses.end());
|
||||||
|
|
||||||
|
// User visible label
|
||||||
|
size_t num_usages = unique_uses.size();
|
||||||
|
code_lens.command->title = std::to_string(num_usages) + " ";
|
||||||
|
if (num_usages == 1)
|
||||||
|
code_lens.command->title += singular;
|
||||||
|
else
|
||||||
|
code_lens.command->title += plural;
|
||||||
|
|
||||||
|
if (force_display || unique_uses.size() > 0)
|
||||||
|
common->result->push_back(code_lens);
|
||||||
|
}
|
||||||
|
|
||||||
struct TextDocumentCodeLensHandler
|
struct TextDocumentCodeLensHandler
|
||||||
: BaseMessageHandler<Ipc_TextDocumentCodeLens> {
|
: BaseMessageHandler<Ipc_TextDocumentCodeLens> {
|
||||||
void Run(Ipc_TextDocumentCodeLens* request) override {
|
void Run(Ipc_TextDocumentCodeLens* request) override {
|
||||||
|
@ -2,6 +2,107 @@
|
|||||||
|
|
||||||
#include "lex_utils.h"
|
#include "lex_utils.h"
|
||||||
|
|
||||||
|
#include <loguru.hpp>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
struct Ipc_TextDocumentComplete : public IpcMessage<Ipc_TextDocumentComplete> {
|
||||||
|
const static IpcId kIpcId = IpcId::TextDocumentCompletion;
|
||||||
|
|
||||||
|
lsRequestId id;
|
||||||
|
lsTextDocumentPositionParams params;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_TextDocumentComplete, id, params);
|
||||||
|
REGISTER_IPC_MESSAGE(Ipc_TextDocumentComplete);
|
||||||
|
|
||||||
|
struct lsTextDocumentCompleteResult {
|
||||||
|
// This list it not complete. Further typing should result in recomputing
|
||||||
|
// this list.
|
||||||
|
bool isIncomplete = false;
|
||||||
|
// The completion items.
|
||||||
|
NonElidedVector<lsCompletionItem> items;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(lsTextDocumentCompleteResult, isIncomplete, items);
|
||||||
|
|
||||||
|
struct Out_TextDocumentComplete
|
||||||
|
: public lsOutMessage<Out_TextDocumentComplete> {
|
||||||
|
lsRequestId id;
|
||||||
|
lsTextDocumentCompleteResult result;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Out_TextDocumentComplete, jsonrpc, id, result);
|
||||||
|
|
||||||
|
// Pre-filters completion responses before sending to vscode. This results in a
|
||||||
|
// significantly snappier completion experience as vscode is easily overloaded
|
||||||
|
// when given 1000+ completion items.
|
||||||
|
void FilterCompletionResponse(Out_TextDocumentComplete* complete_response,
|
||||||
|
const std::string& complete_text) {
|
||||||
|
// Used to inject more completions.
|
||||||
|
#if false
|
||||||
|
const size_t kNumIterations = 250;
|
||||||
|
size_t size = complete_response->result.items.size();
|
||||||
|
complete_response->result.items.reserve(size * (kNumIterations + 1));
|
||||||
|
for (size_t iteration = 0; iteration < kNumIterations; ++iteration) {
|
||||||
|
for (size_t i = 0; i < size; ++i) {
|
||||||
|
auto item = complete_response->result.items[i];
|
||||||
|
item.label += "#" + std::to_string(iteration);
|
||||||
|
complete_response->result.items.push_back(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const size_t kMaxResultSize = 100u;
|
||||||
|
if (complete_response->result.items.size() > kMaxResultSize) {
|
||||||
|
if (complete_text.empty()) {
|
||||||
|
complete_response->result.items.resize(kMaxResultSize);
|
||||||
|
} else {
|
||||||
|
NonElidedVector<lsCompletionItem> filtered_result;
|
||||||
|
filtered_result.reserve(kMaxResultSize);
|
||||||
|
|
||||||
|
std::unordered_set<std::string> inserted;
|
||||||
|
inserted.reserve(kMaxResultSize);
|
||||||
|
|
||||||
|
// Find literal matches first.
|
||||||
|
for (const lsCompletionItem& item : complete_response->result.items) {
|
||||||
|
if (item.label.find(complete_text) != std::string::npos) {
|
||||||
|
// Don't insert the same completion entry.
|
||||||
|
if (!inserted.insert(item.InsertedContent()).second)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
filtered_result.push_back(item);
|
||||||
|
if (filtered_result.size() >= kMaxResultSize)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find fuzzy matches if we haven't found all of the literal matches.
|
||||||
|
if (filtered_result.size() < kMaxResultSize) {
|
||||||
|
for (const lsCompletionItem& item : complete_response->result.items) {
|
||||||
|
if (SubstringMatch(complete_text, item.label)) {
|
||||||
|
// Don't insert the same completion entry.
|
||||||
|
if (!inserted.insert(item.InsertedContent()).second)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
filtered_result.push_back(item);
|
||||||
|
if (filtered_result.size() >= kMaxResultSize)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
complete_response->result.items = filtered_result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assuming the client does not support out-of-order completion (ie, ao
|
||||||
|
// matches against oa), our filtering is guaranteed to contain any
|
||||||
|
// potential matches, so the completion is only incomplete if we have the
|
||||||
|
// max number of emitted matches.
|
||||||
|
if (complete_response->result.items.size() >= kMaxResultSize) {
|
||||||
|
LOG_S(INFO) << "Marking completion results as incomplete";
|
||||||
|
complete_response->result.isIncomplete = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct TextDocumentCompletionHandler : MessageHandler {
|
struct TextDocumentCompletionHandler : MessageHandler {
|
||||||
IpcId GetId() const override { return IpcId::TextDocumentCompletion; }
|
IpcId GetId() const override { return IpcId::TextDocumentCompletion; }
|
||||||
|
|
||||||
@ -122,3 +223,5 @@ struct TextDocumentCompletionHandler : MessageHandler {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
REGISTER_MESSAGE_HANDLER(TextDocumentCompletionHandler);
|
REGISTER_MESSAGE_HANDLER(TextDocumentCompletionHandler);
|
||||||
|
|
||||||
|
} // namespace
|
@ -9,6 +9,23 @@ void PushBack(NonElidedVector<lsLocation>* result,
|
|||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
struct Ipc_TextDocumentDefinition
|
||||||
|
: public IpcMessage<Ipc_TextDocumentDefinition> {
|
||||||
|
const static IpcId kIpcId = IpcId::TextDocumentDefinition;
|
||||||
|
|
||||||
|
lsRequestId id;
|
||||||
|
lsTextDocumentPositionParams params;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_TextDocumentDefinition, id, params);
|
||||||
|
REGISTER_IPC_MESSAGE(Ipc_TextDocumentDefinition);
|
||||||
|
|
||||||
|
struct Out_TextDocumentDefinition
|
||||||
|
: public lsOutMessage<Out_TextDocumentDefinition> {
|
||||||
|
lsRequestId id;
|
||||||
|
NonElidedVector<lsLocation> result;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Out_TextDocumentDefinition, jsonrpc, id, result);
|
||||||
|
|
||||||
struct TextDocumentDefinitionHandler
|
struct TextDocumentDefinitionHandler
|
||||||
: BaseMessageHandler<Ipc_TextDocumentDefinition> {
|
: BaseMessageHandler<Ipc_TextDocumentDefinition> {
|
||||||
void Run(Ipc_TextDocumentDefinition* request) override {
|
void Run(Ipc_TextDocumentDefinition* request) override {
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
#include "message_handler.h"
|
#include "message_handler.h"
|
||||||
|
|
||||||
|
struct Ipc_TextDocumentDidChange
|
||||||
|
: public IpcMessage<Ipc_TextDocumentDidChange> {
|
||||||
|
const static IpcId kIpcId = IpcId::TextDocumentDidChange;
|
||||||
|
lsTextDocumentDidChangeParams params;
|
||||||
|
};
|
||||||
|
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_TextDocumentDidChange, params);
|
||||||
|
REGISTER_IPC_MESSAGE(Ipc_TextDocumentDidChange);
|
||||||
|
|
||||||
struct TextDocumentDidChangeHandler
|
struct TextDocumentDidChangeHandler
|
||||||
: BaseMessageHandler<Ipc_TextDocumentDidChange> {
|
: BaseMessageHandler<Ipc_TextDocumentDidChange> {
|
||||||
void Run(Ipc_TextDocumentDidChange* request) override {
|
void Run(Ipc_TextDocumentDidChange* request) override {
|
||||||
|
@ -1,5 +1,17 @@
|
|||||||
#include "message_handler.h"
|
#include "message_handler.h"
|
||||||
|
|
||||||
|
struct Ipc_TextDocumentDidClose : public IpcMessage<Ipc_TextDocumentDidClose> {
|
||||||
|
struct Params {
|
||||||
|
lsTextDocumentItem textDocument;
|
||||||
|
};
|
||||||
|
|
||||||
|
const static IpcId kIpcId = IpcId::TextDocumentDidClose;
|
||||||
|
Params params;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_TextDocumentDidClose::Params, textDocument);
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_TextDocumentDidClose, params);
|
||||||
|
REGISTER_IPC_MESSAGE(Ipc_TextDocumentDidClose);
|
||||||
|
|
||||||
struct TextDocumentDidCloseHandler
|
struct TextDocumentDidCloseHandler
|
||||||
: BaseMessageHandler<Ipc_TextDocumentDidClose> {
|
: BaseMessageHandler<Ipc_TextDocumentDidClose> {
|
||||||
void Run(Ipc_TextDocumentDidClose* request) override {
|
void Run(Ipc_TextDocumentDidClose* request) override {
|
||||||
@ -11,7 +23,7 @@ struct TextDocumentDidCloseHandler
|
|||||||
IpcManager::WriteStdout(IpcId::TextDocumentPublishDiagnostics, out);
|
IpcManager::WriteStdout(IpcId::TextDocumentPublishDiagnostics, out);
|
||||||
|
|
||||||
// Remove internal state.
|
// Remove internal state.
|
||||||
working_files->OnClose(request->params);
|
working_files->OnClose(request->params.textDocument);
|
||||||
clang_complete->NotifyClose(path);
|
clang_complete->NotifyClose(path);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -2,6 +2,19 @@
|
|||||||
#include "message_handler.h"
|
#include "message_handler.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
|
|
||||||
|
// Open, view, change, close file
|
||||||
|
struct Ipc_TextDocumentDidOpen : public IpcMessage<Ipc_TextDocumentDidOpen> {
|
||||||
|
struct Params {
|
||||||
|
lsTextDocumentItem textDocument;
|
||||||
|
};
|
||||||
|
|
||||||
|
const static IpcId kIpcId = IpcId::TextDocumentDidOpen;
|
||||||
|
Params params;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_TextDocumentDidOpen::Params, textDocument);
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_TextDocumentDidOpen, params);
|
||||||
|
REGISTER_IPC_MESSAGE(Ipc_TextDocumentDidOpen);
|
||||||
|
|
||||||
struct TextDocumentDidOpenHandler
|
struct TextDocumentDidOpenHandler
|
||||||
: BaseMessageHandler<Ipc_TextDocumentDidOpen> {
|
: BaseMessageHandler<Ipc_TextDocumentDidOpen> {
|
||||||
void Run(Ipc_TextDocumentDidOpen* request) override {
|
void Run(Ipc_TextDocumentDidOpen* request) override {
|
||||||
@ -10,7 +23,8 @@ struct TextDocumentDidOpenHandler
|
|||||||
|
|
||||||
Timer time;
|
Timer time;
|
||||||
std::string path = request->params.textDocument.uri.GetPath();
|
std::string path = request->params.textDocument.uri.GetPath();
|
||||||
WorkingFile* working_file = working_files->OnOpen(request->params);
|
WorkingFile* working_file =
|
||||||
|
working_files->OnOpen(request->params.textDocument);
|
||||||
optional<std::string> cached_file_contents =
|
optional<std::string> cached_file_contents =
|
||||||
LoadCachedFileContents(config, path);
|
LoadCachedFileContents(config, path);
|
||||||
if (cached_file_contents)
|
if (cached_file_contents)
|
||||||
|
@ -1,5 +1,22 @@
|
|||||||
#include "message_handler.h"
|
#include "message_handler.h"
|
||||||
|
|
||||||
|
struct Ipc_TextDocumentDidSave : public IpcMessage<Ipc_TextDocumentDidSave> {
|
||||||
|
struct Params {
|
||||||
|
// The document that was saved.
|
||||||
|
lsTextDocumentIdentifier textDocument;
|
||||||
|
|
||||||
|
// Optional the content when saved. Depends on the includeText value
|
||||||
|
// when the save notifcation was requested.
|
||||||
|
// std::string text;
|
||||||
|
};
|
||||||
|
|
||||||
|
const static IpcId kIpcId = IpcId::TextDocumentDidSave;
|
||||||
|
Params params;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_TextDocumentDidSave::Params, textDocument);
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_TextDocumentDidSave, params);
|
||||||
|
REGISTER_IPC_MESSAGE(Ipc_TextDocumentDidSave);
|
||||||
|
|
||||||
struct TextDocumentDidSaveHandler
|
struct TextDocumentDidSaveHandler
|
||||||
: BaseMessageHandler<Ipc_TextDocumentDidSave> {
|
: BaseMessageHandler<Ipc_TextDocumentDidSave> {
|
||||||
void Run(Ipc_TextDocumentDidSave* request) override {
|
void Run(Ipc_TextDocumentDidSave* request) override {
|
||||||
|
@ -3,6 +3,40 @@
|
|||||||
|
|
||||||
#include <loguru.hpp>
|
#include <loguru.hpp>
|
||||||
|
|
||||||
|
struct Ipc_TextDocumentDocumentLink
|
||||||
|
: public IpcMessage<Ipc_TextDocumentDocumentLink> {
|
||||||
|
const static IpcId kIpcId = IpcId::TextDocumentDocumentLink;
|
||||||
|
|
||||||
|
struct DocumentLinkParams {
|
||||||
|
// The document to provide document links for.
|
||||||
|
lsTextDocumentIdentifier textDocument;
|
||||||
|
};
|
||||||
|
|
||||||
|
lsRequestId id;
|
||||||
|
DocumentLinkParams params;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_TextDocumentDocumentLink::DocumentLinkParams,
|
||||||
|
textDocument);
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_TextDocumentDocumentLink, id, params);
|
||||||
|
REGISTER_IPC_MESSAGE(Ipc_TextDocumentDocumentLink);
|
||||||
|
|
||||||
|
// A document link is a range in a text document that links to an internal or
|
||||||
|
// external resource, like another text document or a web site.
|
||||||
|
struct lsDocumentLink {
|
||||||
|
// The range this link applies to.
|
||||||
|
lsRange range;
|
||||||
|
// The uri this link points to. If missing a resolve request is sent later.
|
||||||
|
optional<lsDocumentUri> target;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(lsDocumentLink, range, target);
|
||||||
|
|
||||||
|
struct Out_TextDocumentDocumentLink
|
||||||
|
: public lsOutMessage<Out_TextDocumentDocumentLink> {
|
||||||
|
lsRequestId id;
|
||||||
|
NonElidedVector<lsDocumentLink> result;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Out_TextDocumentDocumentLink, jsonrpc, id, result);
|
||||||
|
|
||||||
struct TextDocumentDocumentLinkHandler
|
struct TextDocumentDocumentLinkHandler
|
||||||
: BaseMessageHandler<Ipc_TextDocumentDocumentLink> {
|
: BaseMessageHandler<Ipc_TextDocumentDocumentLink> {
|
||||||
void Run(Ipc_TextDocumentDocumentLink* request) override {
|
void Run(Ipc_TextDocumentDocumentLink* request) override {
|
||||||
|
@ -1,6 +1,28 @@
|
|||||||
#include "message_handler.h"
|
#include "message_handler.h"
|
||||||
#include "query_utils.h"
|
#include "query_utils.h"
|
||||||
|
|
||||||
|
struct lsDocumentSymbolParams {
|
||||||
|
lsTextDocumentIdentifier textDocument;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(lsDocumentSymbolParams, textDocument);
|
||||||
|
|
||||||
|
struct Ipc_TextDocumentDocumentSymbol
|
||||||
|
: public IpcMessage<Ipc_TextDocumentDocumentSymbol> {
|
||||||
|
const static IpcId kIpcId = IpcId::TextDocumentDocumentSymbol;
|
||||||
|
|
||||||
|
lsRequestId id;
|
||||||
|
lsDocumentSymbolParams params;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_TextDocumentDocumentSymbol, id, params);
|
||||||
|
REGISTER_IPC_MESSAGE(Ipc_TextDocumentDocumentSymbol);
|
||||||
|
|
||||||
|
struct Out_TextDocumentDocumentSymbol
|
||||||
|
: public lsOutMessage<Out_TextDocumentDocumentSymbol> {
|
||||||
|
lsRequestId id;
|
||||||
|
NonElidedVector<lsSymbolInformation> result;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Out_TextDocumentDocumentSymbol, jsonrpc, id, result);
|
||||||
|
|
||||||
struct TextDocumentDocumentSymbolHandler
|
struct TextDocumentDocumentSymbolHandler
|
||||||
: BaseMessageHandler<Ipc_TextDocumentDocumentSymbol> {
|
: BaseMessageHandler<Ipc_TextDocumentDocumentSymbol> {
|
||||||
void Run(Ipc_TextDocumentDocumentSymbol* request) override {
|
void Run(Ipc_TextDocumentDocumentSymbol* request) override {
|
||||||
|
@ -1,6 +1,23 @@
|
|||||||
#include "message_handler.h"
|
#include "message_handler.h"
|
||||||
#include "query_utils.h"
|
#include "query_utils.h"
|
||||||
|
|
||||||
|
struct Ipc_TextDocumentDocumentHighlight
|
||||||
|
: public IpcMessage<Ipc_TextDocumentDocumentHighlight> {
|
||||||
|
const static IpcId kIpcId = IpcId::TextDocumentDocumentHighlight;
|
||||||
|
|
||||||
|
lsRequestId id;
|
||||||
|
lsTextDocumentPositionParams params;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_TextDocumentDocumentHighlight, id, params);
|
||||||
|
REGISTER_IPC_MESSAGE(Ipc_TextDocumentDocumentHighlight);
|
||||||
|
|
||||||
|
struct Out_TextDocumentDocumentHighlight
|
||||||
|
: public lsOutMessage<Out_TextDocumentDocumentHighlight> {
|
||||||
|
lsRequestId id;
|
||||||
|
NonElidedVector<lsDocumentHighlight> result;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Out_TextDocumentDocumentHighlight, jsonrpc, id, result);
|
||||||
|
|
||||||
struct TextDocumentDocumentHighlightHandler
|
struct TextDocumentDocumentHighlightHandler
|
||||||
: BaseMessageHandler<Ipc_TextDocumentDocumentHighlight> {
|
: BaseMessageHandler<Ipc_TextDocumentDocumentHighlight> {
|
||||||
void Run(Ipc_TextDocumentDocumentHighlight* request) override {
|
void Run(Ipc_TextDocumentDocumentHighlight* request) override {
|
||||||
|
@ -1,6 +1,27 @@
|
|||||||
#include "message_handler.h"
|
#include "message_handler.h"
|
||||||
#include "query_utils.h"
|
#include "query_utils.h"
|
||||||
|
|
||||||
|
struct Ipc_TextDocumentHover : public IpcMessage<Ipc_TextDocumentHover> {
|
||||||
|
const static IpcId kIpcId = IpcId::TextDocumentHover;
|
||||||
|
|
||||||
|
lsRequestId id;
|
||||||
|
lsTextDocumentPositionParams params;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_TextDocumentHover, id, params);
|
||||||
|
REGISTER_IPC_MESSAGE(Ipc_TextDocumentHover);
|
||||||
|
|
||||||
|
struct Out_TextDocumentHover : public lsOutMessage<Out_TextDocumentHover> {
|
||||||
|
struct Result {
|
||||||
|
lsMarkedString contents;
|
||||||
|
optional<lsRange> range;
|
||||||
|
};
|
||||||
|
|
||||||
|
lsRequestId id;
|
||||||
|
Result result;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Out_TextDocumentHover::Result, contents, range);
|
||||||
|
MAKE_REFLECT_STRUCT(Out_TextDocumentHover, jsonrpc, id, result);
|
||||||
|
|
||||||
struct TextDocumentHoverHandler : BaseMessageHandler<Ipc_TextDocumentHover> {
|
struct TextDocumentHoverHandler : BaseMessageHandler<Ipc_TextDocumentHover> {
|
||||||
void Run(Ipc_TextDocumentHover* request) override {
|
void Run(Ipc_TextDocumentHover* request) override {
|
||||||
QueryFile* file;
|
QueryFile* file;
|
||||||
|
@ -3,6 +3,39 @@
|
|||||||
|
|
||||||
#include <loguru.hpp>
|
#include <loguru.hpp>
|
||||||
|
|
||||||
|
struct Ipc_TextDocumentReferences
|
||||||
|
: public IpcMessage<Ipc_TextDocumentReferences> {
|
||||||
|
struct lsReferenceContext {
|
||||||
|
// Include the declaration of the current symbol.
|
||||||
|
bool includeDeclaration;
|
||||||
|
};
|
||||||
|
struct lsReferenceParams : public lsTextDocumentPositionParams {
|
||||||
|
lsTextDocumentIdentifier textDocument;
|
||||||
|
lsPosition position;
|
||||||
|
lsReferenceContext context;
|
||||||
|
};
|
||||||
|
|
||||||
|
const static IpcId kIpcId = IpcId::TextDocumentReferences;
|
||||||
|
|
||||||
|
lsRequestId id;
|
||||||
|
lsReferenceParams params;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_TextDocumentReferences::lsReferenceContext,
|
||||||
|
includeDeclaration);
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_TextDocumentReferences::lsReferenceParams,
|
||||||
|
textDocument,
|
||||||
|
position,
|
||||||
|
context);
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_TextDocumentReferences, id, params);
|
||||||
|
REGISTER_IPC_MESSAGE(Ipc_TextDocumentReferences);
|
||||||
|
|
||||||
|
struct Out_TextDocumentReferences
|
||||||
|
: public lsOutMessage<Out_TextDocumentReferences> {
|
||||||
|
lsRequestId id;
|
||||||
|
NonElidedVector<lsLocation> result;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Out_TextDocumentReferences, jsonrpc, id, result);
|
||||||
|
|
||||||
struct TextDocumentReferencesHandler
|
struct TextDocumentReferencesHandler
|
||||||
: BaseMessageHandler<Ipc_TextDocumentReferences> {
|
: BaseMessageHandler<Ipc_TextDocumentReferences> {
|
||||||
void Run(Ipc_TextDocumentReferences* request) override {
|
void Run(Ipc_TextDocumentReferences* request) override {
|
||||||
|
@ -1,6 +1,37 @@
|
|||||||
#include "message_handler.h"
|
#include "message_handler.h"
|
||||||
#include "query_utils.h"
|
#include "query_utils.h"
|
||||||
|
|
||||||
|
struct Ipc_TextDocumentRename : public IpcMessage<Ipc_TextDocumentRename> {
|
||||||
|
struct Params {
|
||||||
|
// The document to format.
|
||||||
|
lsTextDocumentIdentifier textDocument;
|
||||||
|
|
||||||
|
// The position at which this request was sent.
|
||||||
|
lsPosition position;
|
||||||
|
|
||||||
|
// The new name of the symbol. If the given name is not valid the
|
||||||
|
// request must return a [ResponseError](#ResponseError) with an
|
||||||
|
// appropriate message set.
|
||||||
|
std::string newName;
|
||||||
|
};
|
||||||
|
const static IpcId kIpcId = IpcId::TextDocumentRename;
|
||||||
|
|
||||||
|
lsRequestId id;
|
||||||
|
Params params;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_TextDocumentRename::Params,
|
||||||
|
textDocument,
|
||||||
|
position,
|
||||||
|
newName);
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_TextDocumentRename, id, params);
|
||||||
|
REGISTER_IPC_MESSAGE(Ipc_TextDocumentRename);
|
||||||
|
|
||||||
|
struct Out_TextDocumentRename : public lsOutMessage<Out_TextDocumentRename> {
|
||||||
|
lsRequestId id;
|
||||||
|
lsWorkspaceEdit result;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Out_TextDocumentRename, jsonrpc, id, result);
|
||||||
|
|
||||||
struct TextDocumentRenameHandler : BaseMessageHandler<Ipc_TextDocumentRename> {
|
struct TextDocumentRenameHandler : BaseMessageHandler<Ipc_TextDocumentRename> {
|
||||||
void Run(Ipc_TextDocumentRename* request) override {
|
void Run(Ipc_TextDocumentRename* request) override {
|
||||||
QueryFileId file_id;
|
QueryFileId file_id;
|
||||||
|
@ -1,6 +1,83 @@
|
|||||||
#include "message_handler.h"
|
#include "message_handler.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
|
|
||||||
|
struct Ipc_TextDocumentSignatureHelp
|
||||||
|
: public IpcMessage<Ipc_TextDocumentSignatureHelp> {
|
||||||
|
const static IpcId kIpcId = IpcId::TextDocumentSignatureHelp;
|
||||||
|
|
||||||
|
lsRequestId id;
|
||||||
|
lsTextDocumentPositionParams params;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_TextDocumentSignatureHelp, id, params);
|
||||||
|
REGISTER_IPC_MESSAGE(Ipc_TextDocumentSignatureHelp);
|
||||||
|
|
||||||
|
// Represents a parameter of a callable-signature. A parameter can
|
||||||
|
// have a label and a doc-comment.
|
||||||
|
struct lsParameterInformation {
|
||||||
|
// The label of this parameter. Will be shown in
|
||||||
|
// the UI.
|
||||||
|
std::string label;
|
||||||
|
|
||||||
|
// The human-readable doc-comment of this parameter. Will be shown
|
||||||
|
// in the UI but can be omitted.
|
||||||
|
optional<std::string> documentation;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(lsParameterInformation, label, documentation);
|
||||||
|
|
||||||
|
// Represents the signature of something callable. A signature
|
||||||
|
// can have a label, like a function-name, a doc-comment, and
|
||||||
|
// a set of parameters.
|
||||||
|
struct lsSignatureInformation {
|
||||||
|
// The label of this signature. Will be shown in
|
||||||
|
// the UI.
|
||||||
|
std::string label;
|
||||||
|
|
||||||
|
// The human-readable doc-comment of this signature. Will be shown
|
||||||
|
// in the UI but can be omitted.
|
||||||
|
optional<std::string> documentation;
|
||||||
|
|
||||||
|
// The parameters of this signature.
|
||||||
|
std::vector<lsParameterInformation> parameters;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(lsSignatureInformation, label, documentation, parameters);
|
||||||
|
|
||||||
|
// Signature help represents the signature of something
|
||||||
|
// callable. There can be multiple signature but only one
|
||||||
|
// active and only one active parameter.
|
||||||
|
struct lsSignatureHelp {
|
||||||
|
// One or more signatures.
|
||||||
|
NonElidedVector<lsSignatureInformation> signatures;
|
||||||
|
|
||||||
|
// The active signature. If omitted or the value lies outside the
|
||||||
|
// range of `signatures` the value defaults to zero or is ignored if
|
||||||
|
// `signatures.length === 0`. Whenever possible implementors should
|
||||||
|
// make an active decision about the active signature and shouldn't
|
||||||
|
// rely on a default value.
|
||||||
|
// In future version of the protocol this property might become
|
||||||
|
// mandantory to better express this.
|
||||||
|
optional<int> activeSignature;
|
||||||
|
|
||||||
|
// The active parameter of the active signature. If omitted or the value
|
||||||
|
// lies outside the range of `signatures[activeSignature].parameters`
|
||||||
|
// defaults to 0 if the active signature has parameters. If
|
||||||
|
// the active signature has no parameters it is ignored.
|
||||||
|
// In future version of the protocol this property might become
|
||||||
|
// mandantory to better express the active parameter if the
|
||||||
|
// active signature does have any.
|
||||||
|
optional<int> activeParameter;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(lsSignatureHelp,
|
||||||
|
signatures,
|
||||||
|
activeSignature,
|
||||||
|
activeParameter);
|
||||||
|
|
||||||
|
struct Out_TextDocumentSignatureHelp
|
||||||
|
: public lsOutMessage<Out_TextDocumentSignatureHelp> {
|
||||||
|
lsRequestId id;
|
||||||
|
lsSignatureHelp result;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Out_TextDocumentSignatureHelp, jsonrpc, id, result);
|
||||||
|
|
||||||
struct TextDocumentSignatureHelpHandler : MessageHandler {
|
struct TextDocumentSignatureHelpHandler : MessageHandler {
|
||||||
IpcId GetId() const override { return IpcId::TextDocumentSignatureHelp; }
|
IpcId GetId() const override { return IpcId::TextDocumentSignatureHelp; }
|
||||||
|
|
||||||
|
@ -4,6 +4,25 @@
|
|||||||
|
|
||||||
#include <loguru.hpp>
|
#include <loguru.hpp>
|
||||||
|
|
||||||
|
struct lsWorkspaceSymbolParams {
|
||||||
|
std::string query;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(lsWorkspaceSymbolParams, query);
|
||||||
|
|
||||||
|
struct Ipc_WorkspaceSymbol : public IpcMessage<Ipc_WorkspaceSymbol> {
|
||||||
|
const static IpcId kIpcId = IpcId::WorkspaceSymbol;
|
||||||
|
lsRequestId id;
|
||||||
|
lsWorkspaceSymbolParams params;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Ipc_WorkspaceSymbol, id, params);
|
||||||
|
REGISTER_IPC_MESSAGE(Ipc_WorkspaceSymbol);
|
||||||
|
|
||||||
|
struct Out_WorkspaceSymbol : public lsOutMessage<Out_WorkspaceSymbol> {
|
||||||
|
lsRequestId id;
|
||||||
|
NonElidedVector<lsSymbolInformation> result;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_STRUCT(Out_WorkspaceSymbol, jsonrpc, id, result);
|
||||||
|
|
||||||
struct WorkspaceSymbolHandler : BaseMessageHandler<Ipc_WorkspaceSymbol> {
|
struct WorkspaceSymbolHandler : BaseMessageHandler<Ipc_WorkspaceSymbol> {
|
||||||
void Run(Ipc_WorkspaceSymbol* request) override {
|
void Run(Ipc_WorkspaceSymbol* request) override {
|
||||||
// TODO: implement fuzzy search, see
|
// TODO: implement fuzzy search, see
|
||||||
|
@ -510,49 +510,6 @@ optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
|
|||||||
return nullopt;
|
return nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddCodeLens(const char* singular,
|
|
||||||
const char* plural,
|
|
||||||
CommonCodeLensParams* common,
|
|
||||||
QueryLocation loc,
|
|
||||||
const std::vector<QueryLocation>& uses,
|
|
||||||
optional<QueryLocation> excluded,
|
|
||||||
bool force_display) {
|
|
||||||
TCodeLens code_lens;
|
|
||||||
optional<lsRange> range = GetLsRange(common->working_file, loc.range);
|
|
||||||
if (!range)
|
|
||||||
return;
|
|
||||||
code_lens.range = *range;
|
|
||||||
code_lens.command = lsCommand<lsCodeLensCommandArguments>();
|
|
||||||
code_lens.command->command = "cquery.showReferences";
|
|
||||||
code_lens.command->arguments.uri = GetLsDocumentUri(common->db, loc.path);
|
|
||||||
code_lens.command->arguments.position = code_lens.range.start;
|
|
||||||
|
|
||||||
// Add unique uses.
|
|
||||||
std::unordered_set<lsLocation> unique_uses;
|
|
||||||
for (const QueryLocation& use : uses) {
|
|
||||||
if (excluded == use)
|
|
||||||
continue;
|
|
||||||
optional<lsLocation> location =
|
|
||||||
GetLsLocation(common->db, common->working_files, use);
|
|
||||||
if (!location)
|
|
||||||
continue;
|
|
||||||
unique_uses.insert(*location);
|
|
||||||
}
|
|
||||||
code_lens.command->arguments.locations.assign(unique_uses.begin(),
|
|
||||||
unique_uses.end());
|
|
||||||
|
|
||||||
// User visible label
|
|
||||||
size_t num_usages = unique_uses.size();
|
|
||||||
code_lens.command->title = std::to_string(num_usages) + " ";
|
|
||||||
if (num_usages == 1)
|
|
||||||
code_lens.command->title += singular;
|
|
||||||
else
|
|
||||||
code_lens.command->title += plural;
|
|
||||||
|
|
||||||
if (force_display || unique_uses.size() > 0)
|
|
||||||
common->result->push_back(code_lens);
|
|
||||||
}
|
|
||||||
|
|
||||||
lsWorkspaceEdit BuildWorkspaceEdit(QueryDatabase* db,
|
lsWorkspaceEdit BuildWorkspaceEdit(QueryDatabase* db,
|
||||||
WorkingFiles* working_files,
|
WorkingFiles* working_files,
|
||||||
const std::vector<QueryLocation>& locations,
|
const std::vector<QueryLocation>& locations,
|
||||||
@ -639,265 +596,6 @@ std::vector<SymbolRef> FindSymbolsAtLocation(WorkingFile* working_file,
|
|||||||
return symbols;
|
return symbols;
|
||||||
}
|
}
|
||||||
|
|
||||||
NonElidedVector<Out_CqueryTypeHierarchyTree::TypeEntry>
|
|
||||||
BuildParentInheritanceHierarchyForType(QueryDatabase* db,
|
|
||||||
WorkingFiles* working_files,
|
|
||||||
QueryTypeId root) {
|
|
||||||
QueryType& root_type = db->types[root.id];
|
|
||||||
if (!root_type.def)
|
|
||||||
return {};
|
|
||||||
|
|
||||||
NonElidedVector<Out_CqueryTypeHierarchyTree::TypeEntry> parent_entries;
|
|
||||||
parent_entries.reserve(root_type.def->parents.size());
|
|
||||||
|
|
||||||
for (QueryTypeId parent_id : root_type.def->parents) {
|
|
||||||
QueryType& parent_type = db->types[parent_id.id];
|
|
||||||
if (!parent_type.def)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Out_CqueryTypeHierarchyTree::TypeEntry parent_entry;
|
|
||||||
parent_entry.name = parent_type.def->detailed_name;
|
|
||||||
if (parent_type.def->definition_spelling)
|
|
||||||
parent_entry.location = GetLsLocation(
|
|
||||||
db, working_files, *parent_type.def->definition_spelling);
|
|
||||||
parent_entry.children =
|
|
||||||
BuildParentInheritanceHierarchyForType(db, working_files, parent_id);
|
|
||||||
|
|
||||||
parent_entries.push_back(parent_entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
return parent_entries;
|
|
||||||
}
|
|
||||||
|
|
||||||
optional<Out_CqueryTypeHierarchyTree::TypeEntry>
|
|
||||||
BuildInheritanceHierarchyForType(QueryDatabase* db,
|
|
||||||
WorkingFiles* working_files,
|
|
||||||
QueryTypeId root_id) {
|
|
||||||
QueryType& root_type = db->types[root_id.id];
|
|
||||||
if (!root_type.def)
|
|
||||||
return nullopt;
|
|
||||||
|
|
||||||
Out_CqueryTypeHierarchyTree::TypeEntry entry;
|
|
||||||
|
|
||||||
// Name and location.
|
|
||||||
entry.name = root_type.def->detailed_name;
|
|
||||||
if (root_type.def->definition_spelling)
|
|
||||||
entry.location =
|
|
||||||
GetLsLocation(db, working_files, *root_type.def->definition_spelling);
|
|
||||||
|
|
||||||
entry.children.reserve(root_type.derived.size());
|
|
||||||
|
|
||||||
// Base types.
|
|
||||||
Out_CqueryTypeHierarchyTree::TypeEntry base;
|
|
||||||
base.name = "[[Base]]";
|
|
||||||
base.location = entry.location;
|
|
||||||
base.children =
|
|
||||||
BuildParentInheritanceHierarchyForType(db, working_files, root_id);
|
|
||||||
if (!base.children.empty())
|
|
||||||
entry.children.push_back(base);
|
|
||||||
|
|
||||||
// Add derived.
|
|
||||||
for (QueryTypeId derived : root_type.derived) {
|
|
||||||
auto derived_entry =
|
|
||||||
BuildInheritanceHierarchyForType(db, working_files, derived);
|
|
||||||
if (derived_entry)
|
|
||||||
entry.children.push_back(*derived_entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
NonElidedVector<Out_CqueryTypeHierarchyTree::TypeEntry>
|
|
||||||
BuildParentInheritanceHierarchyForFunc(QueryDatabase* db,
|
|
||||||
WorkingFiles* working_files,
|
|
||||||
QueryFuncId root) {
|
|
||||||
QueryFunc& root_func = db->funcs[root.id];
|
|
||||||
if (!root_func.def || !root_func.def->base)
|
|
||||||
return {};
|
|
||||||
|
|
||||||
QueryFunc& parent_func = db->funcs[root_func.def->base->id];
|
|
||||||
if (!parent_func.def)
|
|
||||||
return {};
|
|
||||||
|
|
||||||
Out_CqueryTypeHierarchyTree::TypeEntry parent_entry;
|
|
||||||
parent_entry.name = parent_func.def->detailed_name;
|
|
||||||
if (parent_func.def->definition_spelling)
|
|
||||||
parent_entry.location =
|
|
||||||
GetLsLocation(db, working_files, *parent_func.def->definition_spelling);
|
|
||||||
parent_entry.children = BuildParentInheritanceHierarchyForFunc(
|
|
||||||
db, working_files, *root_func.def->base);
|
|
||||||
|
|
||||||
NonElidedVector<Out_CqueryTypeHierarchyTree::TypeEntry> entries;
|
|
||||||
entries.push_back(parent_entry);
|
|
||||||
return entries;
|
|
||||||
}
|
|
||||||
|
|
||||||
optional<Out_CqueryTypeHierarchyTree::TypeEntry>
|
|
||||||
BuildInheritanceHierarchyForFunc(QueryDatabase* db,
|
|
||||||
WorkingFiles* working_files,
|
|
||||||
QueryFuncId root_id) {
|
|
||||||
QueryFunc& root_func = db->funcs[root_id.id];
|
|
||||||
if (!root_func.def)
|
|
||||||
return nullopt;
|
|
||||||
|
|
||||||
Out_CqueryTypeHierarchyTree::TypeEntry entry;
|
|
||||||
|
|
||||||
// Name and location.
|
|
||||||
entry.name = root_func.def->detailed_name;
|
|
||||||
if (root_func.def->definition_spelling)
|
|
||||||
entry.location =
|
|
||||||
GetLsLocation(db, working_files, *root_func.def->definition_spelling);
|
|
||||||
|
|
||||||
entry.children.reserve(root_func.derived.size());
|
|
||||||
|
|
||||||
// Base types.
|
|
||||||
Out_CqueryTypeHierarchyTree::TypeEntry base;
|
|
||||||
base.name = "[[Base]]";
|
|
||||||
base.location = entry.location;
|
|
||||||
base.children =
|
|
||||||
BuildParentInheritanceHierarchyForFunc(db, working_files, root_id);
|
|
||||||
if (!base.children.empty())
|
|
||||||
entry.children.push_back(base);
|
|
||||||
|
|
||||||
// Add derived.
|
|
||||||
for (QueryFuncId derived : root_func.derived) {
|
|
||||||
auto derived_entry =
|
|
||||||
BuildInheritanceHierarchyForFunc(db, working_files, derived);
|
|
||||||
if (derived_entry)
|
|
||||||
entry.children.push_back(*derived_entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
NonElidedVector<Out_CqueryCallTree::CallEntry> BuildInitialCallTree(
|
|
||||||
QueryDatabase* db,
|
|
||||||
WorkingFiles* working_files,
|
|
||||||
QueryFuncId root) {
|
|
||||||
QueryFunc& root_func = db->funcs[root.id];
|
|
||||||
if (!root_func.def || !root_func.def->definition_spelling)
|
|
||||||
return {};
|
|
||||||
optional<lsLocation> def_loc =
|
|
||||||
GetLsLocation(db, working_files, *root_func.def->definition_spelling);
|
|
||||||
if (!def_loc)
|
|
||||||
return {};
|
|
||||||
|
|
||||||
Out_CqueryCallTree::CallEntry entry;
|
|
||||||
entry.name = root_func.def->short_name;
|
|
||||||
entry.usr = root_func.def->usr;
|
|
||||||
entry.location = *def_loc;
|
|
||||||
entry.hasCallers = HasCallersOnSelfOrBaseOrDerived(db, root_func);
|
|
||||||
NonElidedVector<Out_CqueryCallTree::CallEntry> result;
|
|
||||||
result.push_back(entry);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
NonElidedVector<Out_CqueryCallTree::CallEntry> BuildExpandCallTree(
|
|
||||||
QueryDatabase* db,
|
|
||||||
WorkingFiles* working_files,
|
|
||||||
QueryFuncId root) {
|
|
||||||
QueryFunc& root_func = db->funcs[root.id];
|
|
||||||
if (!root_func.def)
|
|
||||||
return {};
|
|
||||||
|
|
||||||
auto format_location =
|
|
||||||
[&](const lsLocation& location,
|
|
||||||
optional<QueryTypeId> declaring_type) -> std::string {
|
|
||||||
std::string base;
|
|
||||||
|
|
||||||
if (declaring_type) {
|
|
||||||
QueryType type = db->types[declaring_type->id];
|
|
||||||
if (type.def)
|
|
||||||
base = type.def->detailed_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (base.empty()) {
|
|
||||||
base = location.uri.GetPath();
|
|
||||||
size_t last_index = base.find_last_of('/');
|
|
||||||
if (last_index != std::string::npos)
|
|
||||||
base = base.substr(last_index + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return base + ":" + std::to_string(location.range.start.line + 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
NonElidedVector<Out_CqueryCallTree::CallEntry> result;
|
|
||||||
std::unordered_set<QueryLocation> seen_locations;
|
|
||||||
|
|
||||||
auto handle_caller = [&](QueryFuncRef caller,
|
|
||||||
Out_CqueryCallTree::CallType call_type) {
|
|
||||||
optional<lsLocation> call_location =
|
|
||||||
GetLsLocation(db, working_files, caller.loc);
|
|
||||||
if (!call_location)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// TODO: REMOVE |seen_locations| once we fix the querydb update bugs
|
|
||||||
// TODO: REMOVE |seen_locations| once we fix the querydb update bugs
|
|
||||||
// TODO: REMOVE |seen_locations| once we fix the querydb update bugs
|
|
||||||
// TODO: REMOVE |seen_locations| once we fix the querydb update bugs
|
|
||||||
// TODO: REMOVE |seen_locations| once we fix the querydb update bugs
|
|
||||||
// TODO: REMOVE |seen_locations| once we fix the querydb update bugs
|
|
||||||
// TODO: REMOVE |seen_locations| once we fix the querydb update bugs
|
|
||||||
// TODO: REMOVE |seen_locations| once we fix the querydb update bugs
|
|
||||||
// TODO: REMOVE |seen_locations| once we fix the querydb update bugs
|
|
||||||
// TODO: REMOVE |seen_locations| once we fix the querydb update bugs
|
|
||||||
// TODO: REMOVE |seen_locations| once we fix the querydb update bugs
|
|
||||||
// TODO: REMOVE |seen_locations| once we fix the querydb update bugs
|
|
||||||
// TODO: basically, querydb gets duplicate references inserted into it.
|
|
||||||
if (!seen_locations.insert(caller.loc).second) {
|
|
||||||
std::cerr << "!!!! FIXME DUPLICATE REFERENCE IN QUERYDB" << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (caller.has_id()) {
|
|
||||||
QueryFunc& call_func = db->funcs[caller.id_.id];
|
|
||||||
if (!call_func.def)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Out_CqueryCallTree::CallEntry call_entry;
|
|
||||||
call_entry.name =
|
|
||||||
call_func.def->short_name + " (" +
|
|
||||||
format_location(*call_location, call_func.def->declaring_type) + ")";
|
|
||||||
call_entry.usr = call_func.def->usr;
|
|
||||||
call_entry.location = *call_location;
|
|
||||||
call_entry.hasCallers = HasCallersOnSelfOrBaseOrDerived(db, call_func);
|
|
||||||
call_entry.callType = call_type;
|
|
||||||
result.push_back(call_entry);
|
|
||||||
} else {
|
|
||||||
// TODO: See if we can do a better job here. Need more information from
|
|
||||||
// the indexer.
|
|
||||||
Out_CqueryCallTree::CallEntry call_entry;
|
|
||||||
call_entry.name = "Likely Constructor";
|
|
||||||
call_entry.usr = "no_usr";
|
|
||||||
call_entry.location = *call_location;
|
|
||||||
call_entry.hasCallers = false;
|
|
||||||
call_entry.callType = call_type;
|
|
||||||
result.push_back(call_entry);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<QueryFuncRef> base_callers =
|
|
||||||
GetCallersForAllBaseFunctions(db, root_func);
|
|
||||||
std::vector<QueryFuncRef> derived_callers =
|
|
||||||
GetCallersForAllDerivedFunctions(db, root_func);
|
|
||||||
result.reserve(root_func.callers.size() + base_callers.size() +
|
|
||||||
derived_callers.size());
|
|
||||||
|
|
||||||
for (QueryFuncRef caller : root_func.callers)
|
|
||||||
handle_caller(caller, Out_CqueryCallTree::CallType::Direct);
|
|
||||||
for (QueryFuncRef caller : base_callers) {
|
|
||||||
// Do not show calls to the base function coming from this function.
|
|
||||||
if (caller.id_ == root)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
handle_caller(caller, Out_CqueryCallTree::CallType::Base);
|
|
||||||
}
|
|
||||||
for (QueryFuncRef caller : derived_callers)
|
|
||||||
handle_caller(caller, Out_CqueryCallTree::CallType::Derived);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InsertSymbolIntoResult(QueryDatabase* db,
|
void InsertSymbolIntoResult(QueryDatabase* db,
|
||||||
WorkingFiles* working_files,
|
WorkingFiles* working_files,
|
||||||
SymbolIdx symbol,
|
SymbolIdx symbol,
|
||||||
|
@ -61,21 +61,6 @@ optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
|
|||||||
WorkingFiles* working_files,
|
WorkingFiles* working_files,
|
||||||
SymbolIdx symbol);
|
SymbolIdx symbol);
|
||||||
|
|
||||||
struct CommonCodeLensParams {
|
|
||||||
std::vector<TCodeLens>* result;
|
|
||||||
QueryDatabase* db;
|
|
||||||
WorkingFiles* working_files;
|
|
||||||
WorkingFile* working_file;
|
|
||||||
};
|
|
||||||
|
|
||||||
void AddCodeLens(const char* singular,
|
|
||||||
const char* plural,
|
|
||||||
CommonCodeLensParams* common,
|
|
||||||
QueryLocation loc,
|
|
||||||
const std::vector<QueryLocation>& uses,
|
|
||||||
optional<QueryLocation> excluded,
|
|
||||||
bool force_display);
|
|
||||||
|
|
||||||
lsWorkspaceEdit BuildWorkspaceEdit(QueryDatabase* db,
|
lsWorkspaceEdit BuildWorkspaceEdit(QueryDatabase* db,
|
||||||
WorkingFiles* working_files,
|
WorkingFiles* working_files,
|
||||||
const std::vector<QueryLocation>& locations,
|
const std::vector<QueryLocation>& locations,
|
||||||
@ -84,30 +69,6 @@ lsWorkspaceEdit BuildWorkspaceEdit(QueryDatabase* db,
|
|||||||
std::vector<SymbolRef> FindSymbolsAtLocation(WorkingFile* working_file,
|
std::vector<SymbolRef> FindSymbolsAtLocation(WorkingFile* working_file,
|
||||||
QueryFile* file,
|
QueryFile* file,
|
||||||
lsPosition position);
|
lsPosition position);
|
||||||
NonElidedVector<Out_CqueryTypeHierarchyTree::TypeEntry>
|
|
||||||
BuildParentInheritanceHierarchyForType(QueryDatabase* db,
|
|
||||||
WorkingFiles* working_files,
|
|
||||||
QueryTypeId root);
|
|
||||||
optional<Out_CqueryTypeHierarchyTree::TypeEntry>
|
|
||||||
BuildInheritanceHierarchyForType(QueryDatabase* db,
|
|
||||||
WorkingFiles* working_files,
|
|
||||||
QueryTypeId root_id);
|
|
||||||
NonElidedVector<Out_CqueryTypeHierarchyTree::TypeEntry>
|
|
||||||
BuildParentInheritanceHierarchyForFunc(QueryDatabase* db,
|
|
||||||
WorkingFiles* working_files,
|
|
||||||
QueryFuncId root);
|
|
||||||
optional<Out_CqueryTypeHierarchyTree::TypeEntry>
|
|
||||||
BuildInheritanceHierarchyForFunc(QueryDatabase* db,
|
|
||||||
WorkingFiles* working_files,
|
|
||||||
QueryFuncId root_id);
|
|
||||||
NonElidedVector<Out_CqueryCallTree::CallEntry> BuildInitialCallTree(
|
|
||||||
QueryDatabase* db,
|
|
||||||
WorkingFiles* working_files,
|
|
||||||
QueryFuncId root);
|
|
||||||
NonElidedVector<Out_CqueryCallTree::CallEntry> BuildExpandCallTree(
|
|
||||||
QueryDatabase* db,
|
|
||||||
WorkingFiles* working_files,
|
|
||||||
QueryFuncId root);
|
|
||||||
|
|
||||||
// Lookup |symbol| in |db| and insert the value into |result|.
|
// Lookup |symbol| in |db| and insert the value into |result|.
|
||||||
void InsertSymbolIntoResult(QueryDatabase* db,
|
void InsertSymbolIntoResult(QueryDatabase* db,
|
||||||
|
@ -291,15 +291,15 @@ void WorkingFiles::DoActionOnFile(
|
|||||||
action(file);
|
action(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
WorkingFile* WorkingFiles::OnOpen(const Ipc_TextDocumentDidOpen::Params& open) {
|
WorkingFile* WorkingFiles::OnOpen(const lsTextDocumentItem& open) {
|
||||||
std::lock_guard<std::mutex> lock(files_mutex);
|
std::lock_guard<std::mutex> lock(files_mutex);
|
||||||
|
|
||||||
std::string filename = open.textDocument.uri.GetPath();
|
std::string filename = open.uri.GetPath();
|
||||||
std::string content = open.textDocument.text;
|
std::string content = open.text;
|
||||||
|
|
||||||
// The file may already be open.
|
// The file may already be open.
|
||||||
if (WorkingFile* file = GetFileByFilenameNoLock(filename)) {
|
if (WorkingFile* file = GetFileByFilenameNoLock(filename)) {
|
||||||
file->version = open.textDocument.version;
|
file->version = open.version;
|
||||||
file->buffer_content = content;
|
file->buffer_content = content;
|
||||||
file->OnBufferContentUpdated();
|
file->OnBufferContentUpdated();
|
||||||
return file;
|
return file;
|
||||||
@ -309,7 +309,7 @@ WorkingFile* WorkingFiles::OnOpen(const Ipc_TextDocumentDidOpen::Params& open) {
|
|||||||
return files[files.size() - 1].get();
|
return files[files.size() - 1].get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorkingFiles::OnChange(const Ipc_TextDocumentDidChange::Params& change) {
|
void WorkingFiles::OnChange(const lsTextDocumentDidChangeParams& change) {
|
||||||
std::lock_guard<std::mutex> lock(files_mutex);
|
std::lock_guard<std::mutex> lock(files_mutex);
|
||||||
|
|
||||||
std::string filename = change.textDocument.uri.GetPath();
|
std::string filename = change.textDocument.uri.GetPath();
|
||||||
@ -322,8 +322,7 @@ void WorkingFiles::OnChange(const Ipc_TextDocumentDidChange::Params& change) {
|
|||||||
|
|
||||||
file->version = change.textDocument.version;
|
file->version = change.textDocument.version;
|
||||||
|
|
||||||
for (const Ipc_TextDocumentDidChange::lsTextDocumentContentChangeEvent& diff :
|
for (const lsTextDocumentContentChangeEvent& diff : change.contentChanges) {
|
||||||
change.contentChanges) {
|
|
||||||
// Per the spec replace everything if the rangeLength and range are not set.
|
// Per the spec replace everything if the rangeLength and range are not set.
|
||||||
// See https://github.com/Microsoft/language-server-protocol/issues/9.
|
// See https://github.com/Microsoft/language-server-protocol/issues/9.
|
||||||
if (diff.rangeLength == -1 &&
|
if (diff.rangeLength == -1 &&
|
||||||
@ -348,10 +347,10 @@ void WorkingFiles::OnChange(const Ipc_TextDocumentDidChange::Params& change) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorkingFiles::OnClose(const Ipc_TextDocumentDidClose::Params& close) {
|
void WorkingFiles::OnClose(const lsTextDocumentItem& close) {
|
||||||
std::lock_guard<std::mutex> lock(files_mutex);
|
std::lock_guard<std::mutex> lock(files_mutex);
|
||||||
|
|
||||||
std::string filename = close.textDocument.uri.GetPath();
|
std::string filename = close.uri.GetPath();
|
||||||
|
|
||||||
for (int i = 0; i < files.size(); ++i) {
|
for (int i = 0; i < files.size(); ++i) {
|
||||||
if (files[i]->filename == filename) {
|
if (files[i]->filename == filename) {
|
||||||
|
@ -93,9 +93,9 @@ struct WorkingFiles {
|
|||||||
void DoActionOnFile(const std::string& filename,
|
void DoActionOnFile(const std::string& filename,
|
||||||
const std::function<void(WorkingFile* file)>& action);
|
const std::function<void(WorkingFile* file)>& action);
|
||||||
|
|
||||||
WorkingFile* OnOpen(const Ipc_TextDocumentDidOpen::Params& open);
|
WorkingFile* OnOpen(const lsTextDocumentItem& open);
|
||||||
void OnChange(const Ipc_TextDocumentDidChange::Params& change);
|
void OnChange(const lsTextDocumentDidChangeParams& change);
|
||||||
void OnClose(const Ipc_TextDocumentDidClose::Params& close);
|
void OnClose(const lsTextDocumentItem& close);
|
||||||
|
|
||||||
std::vector<CXUnsavedFile> AsUnsavedFiles();
|
std::vector<CXUnsavedFile> AsUnsavedFiles();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user