2017-03-05 02:16:23 +00:00
|
|
|
#pragma once
|
|
|
|
|
2017-05-21 19:51:15 +00:00
|
|
|
#include "config.h"
|
2017-03-25 23:58:11 +00:00
|
|
|
#include "ipc.h"
|
2017-03-25 20:32:44 +00:00
|
|
|
#include "serializer.h"
|
2018-01-06 21:46:41 +00:00
|
|
|
#include "serializers/json.h"
|
2017-03-25 20:32:44 +00:00
|
|
|
#include "utils.h"
|
|
|
|
|
2017-12-29 16:29:10 +00:00
|
|
|
#include <optional.h>
|
2017-03-25 20:32:44 +00:00
|
|
|
#include <rapidjson/writer.h>
|
2017-12-29 16:29:10 +00:00
|
|
|
#include <variant.h>
|
2017-03-25 20:32:44 +00:00
|
|
|
|
2017-03-25 21:57:06 +00:00
|
|
|
#include <algorithm>
|
2018-01-10 18:08:39 +00:00
|
|
|
#include <iostream>
|
2017-03-05 02:16:23 +00:00
|
|
|
#include <unordered_map>
|
|
|
|
#include <unordered_set>
|
|
|
|
|
2017-03-10 07:06:01 +00:00
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
///////////////////////////// OUTGOING MESSAGES /////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
2017-03-12 00:36:00 +00:00
|
|
|
|
2017-03-10 07:06:01 +00:00
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
///////////////////////////// INCOMING MESSAGES /////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
2017-03-05 02:16:23 +00:00
|
|
|
|
2017-12-06 04:05:01 +00:00
|
|
|
#define REGISTER_IPC_MESSAGE(type) \
|
|
|
|
static MessageRegistryRegister<type> type##message_handler_instance_;
|
|
|
|
|
2017-03-10 07:06:01 +00:00
|
|
|
struct MessageRegistry {
|
|
|
|
static MessageRegistry* instance_;
|
|
|
|
static MessageRegistry* instance();
|
2017-03-05 02:16:23 +00:00
|
|
|
|
2017-09-22 01:14:57 +00:00
|
|
|
using Allocator =
|
2018-01-19 22:31:49 +00:00
|
|
|
std::function<void(Reader& visitor, std::unique_ptr<BaseIpcMessage>*)>;
|
2017-03-10 07:06:01 +00:00
|
|
|
std::unordered_map<std::string, Allocator> allocators;
|
2017-03-05 02:16:23 +00:00
|
|
|
|
2018-01-19 22:31:49 +00:00
|
|
|
optional<std::string> ReadMessageFromStdin(
|
|
|
|
std::unique_ptr<BaseIpcMessage>* message);
|
|
|
|
optional<std::string> Parse(Reader& visitor,
|
|
|
|
std::unique_ptr<BaseIpcMessage>* message);
|
2017-12-06 04:05:01 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
struct MessageRegistryRegister {
|
|
|
|
MessageRegistryRegister() {
|
2017-03-25 22:13:19 +00:00
|
|
|
std::string method_name = IpcIdToString(T::kIpcId);
|
2018-01-19 22:31:49 +00:00
|
|
|
MessageRegistry::instance()->allocators[method_name] =
|
|
|
|
[](Reader& visitor, std::unique_ptr<BaseIpcMessage>* message) {
|
|
|
|
*message = MakeUnique<T>();
|
|
|
|
// Reflect may throw and *message will be partially deserialized.
|
|
|
|
Reflect(visitor, static_cast<T&>(**message));
|
|
|
|
};
|
2017-03-05 02:16:23 +00:00
|
|
|
}
|
2017-03-10 07:06:01 +00:00
|
|
|
};
|
2017-03-05 02:16:23 +00:00
|
|
|
|
2017-04-16 20:43:30 +00:00
|
|
|
struct lsBaseOutMessage {
|
2017-06-09 06:20:29 +00:00
|
|
|
virtual ~lsBaseOutMessage();
|
2017-04-16 20:43:30 +00:00
|
|
|
virtual void Write(std::ostream& out) = 0;
|
|
|
|
};
|
2017-03-05 02:16:23 +00:00
|
|
|
|
2017-09-22 01:14:57 +00:00
|
|
|
template <typename TDerived>
|
2017-04-16 20:43:30 +00:00
|
|
|
struct lsOutMessage : lsBaseOutMessage {
|
2017-03-25 21:45:49 +00:00
|
|
|
// All derived types need to reflect on the |jsonrpc| member.
|
|
|
|
std::string jsonrpc = "2.0";
|
2017-03-24 07:59:47 +00:00
|
|
|
|
|
|
|
// Send the message to the language client by writing it to stdout.
|
2017-04-16 20:43:30 +00:00
|
|
|
void Write(std::ostream& out) override {
|
2017-03-24 07:59:47 +00:00
|
|
|
rapidjson::StringBuffer output;
|
2018-01-06 21:46:41 +00:00
|
|
|
rapidjson::Writer<rapidjson::StringBuffer> writer(output);
|
|
|
|
JsonWriter json_writer(&writer);
|
2017-03-25 21:45:49 +00:00
|
|
|
auto that = static_cast<TDerived*>(this);
|
2018-01-06 21:46:41 +00:00
|
|
|
Reflect(json_writer, *that);
|
2017-03-24 07:59:47 +00:00
|
|
|
|
2017-03-25 19:18:25 +00:00
|
|
|
out << "Content-Length: " << output.GetSize();
|
2017-09-22 01:14:57 +00:00
|
|
|
out << (char)13 << char(10) << char(13) << char(10); // CRLFCRLF
|
2017-03-25 19:18:25 +00:00
|
|
|
out << output.GetString();
|
|
|
|
out.flush();
|
2017-03-24 07:59:47 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct lsResponseError {
|
|
|
|
struct Data {
|
|
|
|
virtual void Write(Writer& writer) = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class lsErrorCodes : int {
|
|
|
|
ParseError = -32700,
|
|
|
|
InvalidRequest = -32600,
|
|
|
|
MethodNotFound = -32601,
|
|
|
|
InvalidParams = -32602,
|
|
|
|
InternalError = -32603,
|
|
|
|
serverErrorStart = -32099,
|
|
|
|
serverErrorEnd = -32000,
|
|
|
|
ServerNotInitialized = -32002,
|
|
|
|
UnknownErrorCode = -32001
|
|
|
|
};
|
|
|
|
|
|
|
|
lsErrorCodes code;
|
|
|
|
// Short description.
|
|
|
|
std::string message;
|
|
|
|
std::unique_ptr<Data> data;
|
|
|
|
|
2017-03-25 22:13:19 +00:00
|
|
|
void Write(Writer& visitor);
|
2017-03-24 07:59:47 +00:00
|
|
|
};
|
|
|
|
|
2017-03-10 07:06:01 +00:00
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////// PRIMITIVE TYPES //////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
2017-03-05 02:16:23 +00:00
|
|
|
|
2017-03-10 07:06:01 +00:00
|
|
|
struct lsDocumentUri {
|
2017-03-25 22:13:19 +00:00
|
|
|
static lsDocumentUri FromPath(const std::string& path);
|
2017-03-11 08:07:32 +00:00
|
|
|
|
2017-03-25 22:13:19 +00:00
|
|
|
lsDocumentUri();
|
|
|
|
bool operator==(const lsDocumentUri& other) const;
|
2017-03-25 23:58:11 +00:00
|
|
|
|
2017-03-25 22:13:19 +00:00
|
|
|
void SetPath(const std::string& path);
|
2017-03-26 21:40:34 +00:00
|
|
|
std::string GetPath() const;
|
2017-03-05 02:16:23 +00:00
|
|
|
|
2017-03-25 22:13:19 +00:00
|
|
|
std::string raw_uri;
|
2017-03-10 07:06:01 +00:00
|
|
|
};
|
2017-03-16 07:36:49 +00:00
|
|
|
MAKE_HASHABLE(lsDocumentUri, t.raw_uri);
|
2017-03-05 02:16:23 +00:00
|
|
|
|
2017-09-22 01:14:57 +00:00
|
|
|
template <typename TVisitor>
|
2017-03-10 07:06:01 +00:00
|
|
|
void Reflect(TVisitor& visitor, lsDocumentUri& value) {
|
|
|
|
Reflect(visitor, value.raw_uri);
|
|
|
|
}
|
2017-03-05 02:16:23 +00:00
|
|
|
|
2017-03-10 07:06:01 +00:00
|
|
|
struct lsPosition {
|
2017-03-25 22:13:19 +00:00
|
|
|
lsPosition();
|
|
|
|
lsPosition(int line, int character);
|
|
|
|
|
|
|
|
bool operator==(const lsPosition& other) const;
|
2018-01-10 03:04:08 +00:00
|
|
|
bool operator<(const lsPosition& other) const;
|
2017-03-25 22:13:19 +00:00
|
|
|
|
2017-05-15 07:28:53 +00:00
|
|
|
std::string ToString() const;
|
|
|
|
|
2017-03-10 07:06:01 +00:00
|
|
|
// Note: these are 0-based.
|
|
|
|
int line = 0;
|
|
|
|
int character = 0;
|
2017-11-22 17:52:33 +00:00
|
|
|
static const lsPosition kZeroPosition;
|
2017-03-10 07:06:01 +00:00
|
|
|
};
|
2017-03-16 07:36:49 +00:00
|
|
|
MAKE_HASHABLE(lsPosition, t.line, t.character);
|
2017-03-25 23:58:11 +00:00
|
|
|
MAKE_REFLECT_STRUCT(lsPosition, line, character);
|
2017-03-05 02:16:23 +00:00
|
|
|
|
2017-03-10 07:06:01 +00:00
|
|
|
struct lsRange {
|
2017-03-25 22:13:19 +00:00
|
|
|
lsRange();
|
2017-04-05 08:06:18 +00:00
|
|
|
lsRange(lsPosition start, lsPosition end);
|
2017-03-15 07:14:44 +00:00
|
|
|
|
2017-03-25 22:13:19 +00:00
|
|
|
bool operator==(const lsRange& other) const;
|
2017-03-16 07:36:49 +00:00
|
|
|
|
2017-03-25 22:13:19 +00:00
|
|
|
lsPosition start;
|
|
|
|
lsPosition end;
|
2017-03-10 07:06:01 +00:00
|
|
|
};
|
2017-03-16 07:36:49 +00:00
|
|
|
MAKE_HASHABLE(lsRange, t.start, t.end);
|
2017-03-25 23:58:11 +00:00
|
|
|
MAKE_REFLECT_STRUCT(lsRange, start, end);
|
2017-03-05 02:16:23 +00:00
|
|
|
|
2017-03-10 07:06:01 +00:00
|
|
|
struct lsLocation {
|
2017-03-25 22:13:19 +00:00
|
|
|
lsLocation();
|
|
|
|
lsLocation(lsDocumentUri uri, lsRange range);
|
2017-03-15 07:14:44 +00:00
|
|
|
|
2017-03-25 22:13:19 +00:00
|
|
|
bool operator==(const lsLocation& other) const;
|
2017-03-16 07:36:49 +00:00
|
|
|
|
2017-03-25 22:13:19 +00:00
|
|
|
lsDocumentUri uri;
|
|
|
|
lsRange range;
|
2017-03-10 07:06:01 +00:00
|
|
|
};
|
2017-03-25 23:58:11 +00:00
|
|
|
MAKE_HASHABLE(lsLocation, t.uri, t.range);
|
|
|
|
MAKE_REFLECT_STRUCT(lsLocation, uri, range);
|
2017-03-05 02:16:23 +00:00
|
|
|
|
2017-03-10 07:06:01 +00:00
|
|
|
enum class lsSymbolKind : int {
|
|
|
|
File = 1,
|
|
|
|
Module = 2,
|
|
|
|
Namespace = 3,
|
|
|
|
Package = 4,
|
|
|
|
Class = 5,
|
|
|
|
Method = 6,
|
|
|
|
Property = 7,
|
|
|
|
Field = 8,
|
|
|
|
Constructor = 9,
|
|
|
|
Enum = 10,
|
|
|
|
Interface = 11,
|
|
|
|
Function = 12,
|
|
|
|
Variable = 13,
|
|
|
|
Constant = 14,
|
|
|
|
String = 15,
|
|
|
|
Number = 16,
|
|
|
|
Boolean = 17,
|
|
|
|
Array = 18
|
|
|
|
};
|
2018-01-30 00:35:01 +00:00
|
|
|
MAKE_REFLECT_TYPE_PROXY(lsSymbolKind);
|
2017-03-05 02:16:23 +00:00
|
|
|
|
2017-03-10 07:06:01 +00:00
|
|
|
struct lsSymbolInformation {
|
2018-02-01 05:40:40 +00:00
|
|
|
std::string_view name;
|
2017-03-10 07:06:01 +00:00
|
|
|
lsSymbolKind kind;
|
|
|
|
lsLocation location;
|
2018-02-01 05:40:40 +00:00
|
|
|
std::string_view containerName;
|
2017-03-10 07:06:01 +00:00
|
|
|
};
|
2017-03-25 23:58:11 +00:00
|
|
|
MAKE_REFLECT_STRUCT(lsSymbolInformation, name, kind, location, containerName);
|
2017-03-05 02:16:23 +00:00
|
|
|
|
2017-09-22 01:14:57 +00:00
|
|
|
template <typename T>
|
2017-03-10 07:06:01 +00:00
|
|
|
struct lsCommand {
|
|
|
|
// Title of the command (ie, 'save')
|
|
|
|
std::string title;
|
|
|
|
// Actual command identifier.
|
|
|
|
std::string command;
|
2017-03-15 07:14:44 +00:00
|
|
|
// Arguments to run the command with.
|
2017-05-20 19:31:07 +00:00
|
|
|
// **NOTE** This must be serialized as an array. Use
|
|
|
|
// MAKE_REFLECT_STRUCT_WRITER_AS_ARRAY.
|
2017-03-15 07:14:44 +00:00
|
|
|
T arguments;
|
2017-03-10 07:06:01 +00:00
|
|
|
};
|
2017-09-22 01:14:57 +00:00
|
|
|
template <typename TVisitor, typename T>
|
2017-03-15 07:14:44 +00:00
|
|
|
void Reflect(TVisitor& visitor, lsCommand<T>& value) {
|
2018-01-08 04:10:16 +00:00
|
|
|
REFLECT_MEMBER_START();
|
2017-03-10 07:06:01 +00:00
|
|
|
REFLECT_MEMBER(title);
|
|
|
|
REFLECT_MEMBER(command);
|
|
|
|
REFLECT_MEMBER(arguments);
|
|
|
|
REFLECT_MEMBER_END();
|
|
|
|
}
|
2017-03-05 02:16:23 +00:00
|
|
|
|
2017-09-22 01:14:57 +00:00
|
|
|
template <typename TData, typename TCommandArguments>
|
2017-03-15 07:14:44 +00:00
|
|
|
struct lsCodeLens {
|
|
|
|
// The range in which this code lens is valid. Should only span a single line.
|
|
|
|
lsRange range;
|
|
|
|
// The command this code lens represents.
|
|
|
|
optional<lsCommand<TCommandArguments>> command;
|
|
|
|
// A data entry field that is preserved on a code lens item between
|
|
|
|
// a code lens and a code lens resolve request.
|
|
|
|
TData data;
|
|
|
|
};
|
2017-09-22 01:14:57 +00:00
|
|
|
template <typename TVisitor, typename TData, typename TCommandArguments>
|
2017-03-15 07:14:44 +00:00
|
|
|
void Reflect(TVisitor& visitor, lsCodeLens<TData, TCommandArguments>& value) {
|
2018-01-08 04:10:16 +00:00
|
|
|
REFLECT_MEMBER_START();
|
2017-03-15 07:14:44 +00:00
|
|
|
REFLECT_MEMBER(range);
|
|
|
|
REFLECT_MEMBER(command);
|
|
|
|
REFLECT_MEMBER(data);
|
|
|
|
REFLECT_MEMBER_END();
|
|
|
|
}
|
|
|
|
|
2017-03-10 07:06:01 +00:00
|
|
|
struct lsTextDocumentIdentifier {
|
|
|
|
lsDocumentUri uri;
|
|
|
|
};
|
2017-03-25 23:58:11 +00:00
|
|
|
MAKE_REFLECT_STRUCT(lsTextDocumentIdentifier, uri);
|
2017-03-05 02:16:23 +00:00
|
|
|
|
2017-03-26 06:47:59 +00:00
|
|
|
struct lsVersionedTextDocumentIdentifier {
|
|
|
|
lsDocumentUri uri;
|
2018-01-10 07:57:33 +00:00
|
|
|
// The version number of this document. number | null
|
|
|
|
std::variant<std::monostate, int> version;
|
2017-09-22 02:25:33 +00:00
|
|
|
|
|
|
|
lsTextDocumentIdentifier AsTextDocumentIdentifier() const;
|
2017-03-26 06:47:59 +00:00
|
|
|
};
|
|
|
|
MAKE_REFLECT_STRUCT(lsVersionedTextDocumentIdentifier, uri, version);
|
|
|
|
|
|
|
|
struct lsTextDocumentPositionParams {
|
|
|
|
// The text document.
|
|
|
|
lsTextDocumentIdentifier textDocument;
|
|
|
|
|
|
|
|
// The position inside the text document.
|
|
|
|
lsPosition position;
|
|
|
|
};
|
|
|
|
MAKE_REFLECT_STRUCT(lsTextDocumentPositionParams, textDocument, position);
|
|
|
|
|
2017-05-21 07:37:53 +00:00
|
|
|
struct lsTextEdit {
|
|
|
|
// The range of the text document to be manipulated. To insert
|
|
|
|
// text into a document create a range where start === end.
|
|
|
|
lsRange range;
|
|
|
|
|
|
|
|
// The string to be inserted. For delete operations use an
|
|
|
|
// empty string.
|
|
|
|
std::string newText;
|
|
|
|
|
|
|
|
bool operator==(const lsTextEdit& that);
|
|
|
|
};
|
|
|
|
MAKE_REFLECT_STRUCT(lsTextEdit, range, newText);
|
|
|
|
|
2017-03-26 06:47:59 +00:00
|
|
|
// Defines whether the insert text in a completion item should be interpreted as
|
|
|
|
// plain text or a snippet.
|
|
|
|
enum class lsInsertTextFormat {
|
|
|
|
// The primary text to be inserted is treated as a plain string.
|
|
|
|
PlainText = 1,
|
|
|
|
|
|
|
|
// The primary text to be inserted is treated as a snippet.
|
|
|
|
//
|
|
|
|
// A snippet can define tab stops and placeholders with `$1`, `$2`
|
|
|
|
// and `${3:foo}`. `$0` defines the final tab stop, it defaults to
|
|
|
|
// the end of the snippet. Placeholders with equal identifiers are linked,
|
|
|
|
// that is typing in one will update others too.
|
|
|
|
//
|
2017-09-22 01:14:57 +00:00
|
|
|
// See also:
|
|
|
|
// https://github.com/Microsoft/vscode/blob/master/src/vs/editor/contrib/snippet/common/snippet.md
|
2017-03-26 06:47:59 +00:00
|
|
|
Snippet = 2
|
|
|
|
};
|
2018-01-30 00:35:01 +00:00
|
|
|
MAKE_REFLECT_TYPE_PROXY(lsInsertTextFormat);
|
2017-03-26 06:47:59 +00:00
|
|
|
|
|
|
|
// The kind of a completion entry.
|
|
|
|
enum class lsCompletionItemKind {
|
|
|
|
Text = 1,
|
|
|
|
Method = 2,
|
|
|
|
Function = 3,
|
|
|
|
Constructor = 4,
|
|
|
|
Field = 5,
|
|
|
|
Variable = 6,
|
|
|
|
Class = 7,
|
|
|
|
Interface = 8,
|
|
|
|
Module = 9,
|
|
|
|
Property = 10,
|
|
|
|
Unit = 11,
|
|
|
|
Value = 12,
|
|
|
|
Enum = 13,
|
|
|
|
Keyword = 14,
|
|
|
|
Snippet = 15,
|
|
|
|
Color = 16,
|
|
|
|
File = 17,
|
2017-12-30 00:32:43 +00:00
|
|
|
Reference = 18,
|
|
|
|
Folder = 19,
|
|
|
|
EnumMember = 20,
|
|
|
|
Constant = 21,
|
|
|
|
Struct = 22,
|
|
|
|
Event = 23,
|
|
|
|
Operator = 24,
|
|
|
|
TypeParameter = 25,
|
2017-03-26 06:47:59 +00:00
|
|
|
};
|
2018-01-30 00:35:01 +00:00
|
|
|
MAKE_REFLECT_TYPE_PROXY(lsCompletionItemKind);
|
2017-03-26 06:47:59 +00:00
|
|
|
|
|
|
|
struct lsCompletionItem {
|
2017-09-22 01:14:57 +00:00
|
|
|
// A set of function parameters. Used internally for signature help. Not sent
|
|
|
|
// to vscode.
|
2017-05-15 07:28:53 +00:00
|
|
|
std::vector<std::string> parameters_;
|
|
|
|
|
2017-03-26 06:47:59 +00:00
|
|
|
// The label of this completion item. By default
|
|
|
|
// also the text that is inserted when selecting
|
|
|
|
// this completion.
|
|
|
|
std::string label;
|
|
|
|
|
|
|
|
// The kind of this completion item. Based of the kind
|
|
|
|
// an icon is chosen by the editor.
|
|
|
|
lsCompletionItemKind kind = lsCompletionItemKind::Text;
|
2017-03-05 02:16:23 +00:00
|
|
|
|
2017-03-26 06:47:59 +00:00
|
|
|
// A human-readable string with additional information
|
|
|
|
// about this item, like type or symbol information.
|
|
|
|
std::string detail;
|
2017-03-05 02:16:23 +00:00
|
|
|
|
2017-03-26 06:47:59 +00:00
|
|
|
// A human-readable string that represents a doc-comment.
|
|
|
|
std::string documentation;
|
2017-03-05 02:16:23 +00:00
|
|
|
|
2017-12-30 07:15:46 +00:00
|
|
|
// Internal information to order candidates.
|
2018-02-03 04:36:44 +00:00
|
|
|
bool found_;
|
|
|
|
std::string::size_type skip_;
|
2017-12-30 07:15:46 +00:00
|
|
|
unsigned priority_;
|
|
|
|
|
2017-03-26 06:47:59 +00:00
|
|
|
// A string that shoud be used when comparing this item
|
|
|
|
// with other items. When `falsy` the label is used.
|
|
|
|
std::string sortText;
|
2017-03-05 02:16:23 +00:00
|
|
|
|
2017-03-26 06:47:59 +00:00
|
|
|
// A string that should be used when filtering a set of
|
|
|
|
// completion items. When `falsy` the label is used.
|
add detailedLabel completion style
Some completion UI, such as Emacs' completion-at-point and company-lsp,
display completion item label and detail side by side.
This does not look right, when you see things like:
"foo" "int foo()"
"bar" "void bar(int i = 0)"
When this option is enabled, the completion item label is very detailed,
it shows the full signature of the candidate.
The detail just contains the completion item parent context.
Also, in this mode, functions with default arguments,
generates one more item per default argument
so that the right function call can be selected.
That is, you get something like:
"int foo()" "Foo"
"void bar()" "Foo"
"void bar(int i = 0)" "Foo"
Be wary, this is quickly quite verbose,
items can end up truncated by the UIs.
2018-02-03 17:32:55 +00:00
|
|
|
std::string filterText;
|
2017-03-05 02:16:23 +00:00
|
|
|
|
2017-03-26 06:47:59 +00:00
|
|
|
// A string that should be inserted a document when selecting
|
|
|
|
// this completion. When `falsy` the label is used.
|
2017-05-15 07:28:53 +00:00
|
|
|
std::string insertText;
|
2017-03-05 02:16:23 +00:00
|
|
|
|
2017-09-22 01:14:57 +00:00
|
|
|
// The format of the insert text. The format applies to both the `insertText`
|
|
|
|
// property and the `newText` property of a provided `textEdit`.
|
2017-12-05 17:21:54 +00:00
|
|
|
lsInsertTextFormat insertTextFormat = lsInsertTextFormat::PlainText;
|
2017-03-26 06:47:59 +00:00
|
|
|
|
2017-09-22 01:14:57 +00:00
|
|
|
// An edit which is applied to a document when selecting this completion. When
|
|
|
|
// an edit is provided the value of `insertText` is ignored.
|
2017-03-26 06:47:59 +00:00
|
|
|
//
|
2017-09-22 01:14:57 +00:00
|
|
|
// *Note:* The range of the edit must be a single line range and it must
|
|
|
|
// contain the position at which completion has been requested.
|
2017-05-21 07:37:53 +00:00
|
|
|
optional<lsTextEdit> textEdit;
|
2017-03-26 06:47:59 +00:00
|
|
|
|
|
|
|
// An optional array of additional text edits that are applied when
|
|
|
|
// selecting this completion. Edits must not overlap with the main edit
|
|
|
|
// nor with themselves.
|
|
|
|
// std::vector<TextEdit> additionalTextEdits;
|
|
|
|
|
2017-09-22 01:14:57 +00:00
|
|
|
// An optional command that is executed *after* inserting this completion.
|
|
|
|
// *Note* that additional modifications to the current document should be
|
|
|
|
// described with the additionalTextEdits-property. Command command;
|
2017-03-26 06:47:59 +00:00
|
|
|
|
|
|
|
// An data entry field that is preserved on a completion item between
|
|
|
|
// a completion and a completion resolve request.
|
|
|
|
// data ? : any
|
2017-06-29 06:59:38 +00:00
|
|
|
|
|
|
|
// Use this helper to figure out what content the completion item will insert
|
|
|
|
// into the document, as it could live in either |textEdit|, |insertText|, or
|
|
|
|
// |label|.
|
|
|
|
const std::string& InsertedContent() const;
|
2017-03-26 06:47:59 +00:00
|
|
|
};
|
|
|
|
MAKE_REFLECT_STRUCT(lsCompletionItem,
|
2017-09-22 01:14:57 +00:00
|
|
|
label,
|
|
|
|
kind,
|
|
|
|
detail,
|
|
|
|
documentation,
|
|
|
|
sortText,
|
|
|
|
insertText,
|
add detailedLabel completion style
Some completion UI, such as Emacs' completion-at-point and company-lsp,
display completion item label and detail side by side.
This does not look right, when you see things like:
"foo" "int foo()"
"bar" "void bar(int i = 0)"
When this option is enabled, the completion item label is very detailed,
it shows the full signature of the candidate.
The detail just contains the completion item parent context.
Also, in this mode, functions with default arguments,
generates one more item per default argument
so that the right function call can be selected.
That is, you get something like:
"int foo()" "Foo"
"void bar()" "Foo"
"void bar(int i = 0)" "Foo"
Be wary, this is quickly quite verbose,
items can end up truncated by the UIs.
2018-02-03 17:32:55 +00:00
|
|
|
filterText,
|
2017-09-22 01:14:57 +00:00
|
|
|
insertTextFormat,
|
|
|
|
textEdit);
|
2017-03-26 06:47:59 +00:00
|
|
|
|
|
|
|
struct lsTextDocumentItem {
|
|
|
|
// The text document's URI.
|
|
|
|
lsDocumentUri uri;
|
|
|
|
|
|
|
|
// The text document's language identifier.
|
|
|
|
std::string languageId;
|
|
|
|
|
|
|
|
// The version number of this document (it will strictly increase after each
|
|
|
|
// change, including undo/redo).
|
|
|
|
int version;
|
|
|
|
|
|
|
|
// The content of the opened text document.
|
|
|
|
std::string text;
|
|
|
|
};
|
|
|
|
MAKE_REFLECT_STRUCT(lsTextDocumentItem, uri, languageId, version, text);
|
|
|
|
|
|
|
|
struct lsTextDocumentEdit {
|
|
|
|
// The text document to change.
|
|
|
|
lsVersionedTextDocumentIdentifier textDocument;
|
|
|
|
|
|
|
|
// The edits to be applied.
|
|
|
|
std::vector<lsTextEdit> edits;
|
|
|
|
};
|
|
|
|
MAKE_REFLECT_STRUCT(lsTextDocumentEdit, textDocument, edits);
|
|
|
|
|
2017-04-14 08:21:03 +00:00
|
|
|
struct lsWorkspaceEdit {
|
|
|
|
// Holds changes to existing resources.
|
|
|
|
// changes ? : { [uri:string]: TextEdit[]; };
|
2017-09-22 01:14:57 +00:00
|
|
|
// std::unordered_map<lsDocumentUri, std::vector<lsTextEdit>> changes;
|
2017-04-14 08:21:03 +00:00
|
|
|
|
|
|
|
// An array of `TextDocumentEdit`s to express changes to specific a specific
|
|
|
|
// version of a text document. Whether a client supports versioned document
|
|
|
|
// edits is expressed via `WorkspaceClientCapabilites.versionedWorkspaceEdit`.
|
|
|
|
std::vector<lsTextDocumentEdit> documentChanges;
|
|
|
|
};
|
|
|
|
MAKE_REFLECT_STRUCT(lsWorkspaceEdit, documentChanges);
|
|
|
|
|
2017-04-14 06:43:50 +00:00
|
|
|
// A document highlight kind.
|
|
|
|
enum class lsDocumentHighlightKind {
|
|
|
|
// A textual occurrence.
|
|
|
|
Text = 1,
|
|
|
|
// Read-access of a symbol, like reading a variable.
|
|
|
|
Read = 2,
|
|
|
|
// Write-access of a symbol, like writing to a variable.
|
|
|
|
Write = 3
|
|
|
|
};
|
2018-01-30 00:35:01 +00:00
|
|
|
MAKE_REFLECT_TYPE_PROXY(lsDocumentHighlightKind);
|
2017-04-14 06:43:50 +00:00
|
|
|
|
2018-01-01 03:33:28 +00:00
|
|
|
struct lsFormattingOptions {
|
|
|
|
// Size of a tab in spaces.
|
|
|
|
int tabSize;
|
|
|
|
// Prefer spaces over tabs.
|
|
|
|
bool insertSpaces;
|
|
|
|
};
|
|
|
|
MAKE_REFLECT_STRUCT(lsFormattingOptions, tabSize, insertSpaces);
|
|
|
|
|
2017-04-14 06:43:50 +00:00
|
|
|
// A document highlight is a range inside a text document which deserves
|
|
|
|
// special attention. Usually a document highlight is visualized by changing
|
|
|
|
// the background color of its range.
|
|
|
|
struct lsDocumentHighlight {
|
2017-09-22 01:14:57 +00:00
|
|
|
// The range this highlight applies to.
|
|
|
|
lsRange range;
|
2017-04-14 06:43:50 +00:00
|
|
|
|
2017-09-22 01:14:57 +00:00
|
|
|
// The highlight kind, default is DocumentHighlightKind.Text.
|
2017-04-14 06:43:50 +00:00
|
|
|
lsDocumentHighlightKind kind = lsDocumentHighlightKind::Text;
|
|
|
|
};
|
|
|
|
MAKE_REFLECT_STRUCT(lsDocumentHighlight, range, kind);
|
|
|
|
|
2017-05-10 06:13:13 +00:00
|
|
|
enum class lsDiagnosticSeverity {
|
|
|
|
// Reports an error.
|
|
|
|
Error = 1,
|
|
|
|
// Reports a warning.
|
|
|
|
Warning = 2,
|
|
|
|
// Reports an information.
|
|
|
|
Information = 3,
|
|
|
|
// Reports a hint.
|
|
|
|
Hint = 4
|
|
|
|
};
|
2018-01-30 00:35:01 +00:00
|
|
|
MAKE_REFLECT_TYPE_PROXY(lsDiagnosticSeverity);
|
2017-05-10 06:13:13 +00:00
|
|
|
|
|
|
|
struct lsDiagnostic {
|
|
|
|
// The range at which the message applies.
|
|
|
|
lsRange range;
|
|
|
|
|
|
|
|
// The diagnostic's severity. Can be omitted. If omitted it is up to the
|
|
|
|
// client to interpret diagnostics as error, warning, info or hint.
|
|
|
|
optional<lsDiagnosticSeverity> severity;
|
|
|
|
|
|
|
|
// The diagnostic's code. Can be omitted.
|
|
|
|
int code = 0;
|
|
|
|
|
|
|
|
// A human-readable string describing the source of this
|
|
|
|
// diagnostic, e.g. 'typescript' or 'super lint'.
|
|
|
|
std::string source = "cquery";
|
|
|
|
|
|
|
|
// The diagnostic's message.
|
|
|
|
std::string message;
|
2017-05-20 19:31:07 +00:00
|
|
|
|
|
|
|
// Non-serialized set of fixits.
|
2017-12-12 05:20:29 +00:00
|
|
|
std::vector<lsTextEdit> fixits_;
|
2017-05-10 06:13:13 +00:00
|
|
|
};
|
|
|
|
MAKE_REFLECT_STRUCT(lsDiagnostic, range, severity, source, message);
|
|
|
|
|
2017-05-27 07:10:21 +00:00
|
|
|
enum class lsErrorCodes {
|
|
|
|
// Defined by JSON RPC
|
|
|
|
ParseError = -32700,
|
|
|
|
InvalidRequest = -32600,
|
|
|
|
MethodNotFound = -32601,
|
|
|
|
InvalidParams = -32602,
|
|
|
|
InternalError = -32603,
|
|
|
|
serverErrorStart = -32099,
|
|
|
|
serverErrorEnd = -32000,
|
|
|
|
ServerNotInitialized = -32002,
|
|
|
|
UnknownErrorCode = -32001,
|
|
|
|
|
|
|
|
// Defined by the protocol.
|
|
|
|
RequestCancelled = -32800,
|
|
|
|
};
|
2018-01-30 00:35:01 +00:00
|
|
|
MAKE_REFLECT_TYPE_PROXY(lsErrorCodes);
|
2017-05-27 07:10:21 +00:00
|
|
|
struct Out_Error : public lsOutMessage<Out_Error> {
|
|
|
|
struct lsResponseError {
|
|
|
|
// A number indicating the error type that occurred.
|
|
|
|
lsErrorCodes code;
|
|
|
|
|
|
|
|
// A string providing a short description of the error.
|
|
|
|
std::string message;
|
|
|
|
|
|
|
|
// A Primitive or Structured value that contains additional
|
|
|
|
// information about the error. Can be omitted.
|
|
|
|
// optional<D> data;
|
|
|
|
};
|
2017-03-05 02:16:23 +00:00
|
|
|
|
2017-05-27 07:10:21 +00:00
|
|
|
lsRequestId id;
|
2017-03-05 02:16:23 +00:00
|
|
|
|
2017-05-27 07:10:21 +00:00
|
|
|
// The error object in case a request fails.
|
|
|
|
lsResponseError error;
|
|
|
|
};
|
|
|
|
MAKE_REFLECT_STRUCT(Out_Error::lsResponseError, code, message);
|
|
|
|
MAKE_REFLECT_STRUCT(Out_Error, jsonrpc, id, error);
|
2017-03-05 02:16:23 +00:00
|
|
|
|
2017-03-25 21:45:49 +00:00
|
|
|
// Cancel an existing request.
|
2018-01-19 09:06:02 +00:00
|
|
|
struct Ipc_CancelRequest : public RequestMessage<Ipc_CancelRequest> {
|
2017-03-25 21:57:06 +00:00
|
|
|
static const IpcId kIpcId = IpcId::CancelRequest;
|
2017-03-25 21:02:45 +00:00
|
|
|
};
|
2017-03-25 23:58:11 +00:00
|
|
|
MAKE_REFLECT_STRUCT(Ipc_CancelRequest, id);
|
2017-03-05 02:16:23 +00:00
|
|
|
|
2017-05-10 06:13:13 +00:00
|
|
|
// Diagnostics
|
2017-09-22 01:14:57 +00:00
|
|
|
struct Out_TextDocumentPublishDiagnostics
|
|
|
|
: public lsOutMessage<Out_TextDocumentPublishDiagnostics> {
|
2017-05-10 06:13:13 +00:00
|
|
|
struct Params {
|
|
|
|
// The URI for which diagnostic information is reported.
|
|
|
|
lsDocumentUri uri;
|
|
|
|
|
|
|
|
// An array of diagnostic information items.
|
2017-12-12 05:20:29 +00:00
|
|
|
std::vector<lsDiagnostic> diagnostics;
|
2017-05-10 06:13:13 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
Params params;
|
|
|
|
};
|
2017-09-22 01:14:57 +00:00
|
|
|
template <typename TVisitor>
|
2017-05-10 06:13:13 +00:00
|
|
|
void Reflect(TVisitor& visitor, Out_TextDocumentPublishDiagnostics& value) {
|
|
|
|
std::string method = "textDocument/publishDiagnostics";
|
2018-01-08 04:10:16 +00:00
|
|
|
REFLECT_MEMBER_START();
|
2017-05-10 06:13:13 +00:00
|
|
|
REFLECT_MEMBER(jsonrpc);
|
|
|
|
REFLECT_MEMBER2("method", method);
|
|
|
|
REFLECT_MEMBER(params);
|
|
|
|
REFLECT_MEMBER_END();
|
|
|
|
}
|
2017-09-22 01:14:57 +00:00
|
|
|
MAKE_REFLECT_STRUCT(Out_TextDocumentPublishDiagnostics::Params,
|
|
|
|
uri,
|
|
|
|
diagnostics);
|
2017-05-10 06:13:13 +00:00
|
|
|
|
2017-12-01 17:50:39 +00:00
|
|
|
// 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.
|
|
|
|
// The language identifier is sematically equal to the optional language
|
|
|
|
// identifier in fenced code blocks in GitHub issues. See
|
|
|
|
// https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting
|
2017-11-30 03:47:29 +00:00
|
|
|
//
|
|
|
|
// The pair of a language and a value is an equivalent to markdown:
|
|
|
|
// ```${language}
|
|
|
|
// ${value}
|
|
|
|
// ```
|
|
|
|
//
|
2017-12-01 17:50:39 +00:00
|
|
|
// Note that markdown strings will be sanitized - that means html will be
|
|
|
|
// escaped.
|
2017-12-28 23:21:40 +00:00
|
|
|
struct lsMarkedString1 {
|
2018-01-31 07:48:34 +00:00
|
|
|
std::string_view language;
|
|
|
|
std::string_view value;
|
2017-11-30 03:47:29 +00:00
|
|
|
};
|
2018-01-31 07:48:34 +00:00
|
|
|
using lsMarkedString = std::variant<std::string_view, lsMarkedString1>;
|
2017-12-28 23:21:40 +00:00
|
|
|
MAKE_REFLECT_STRUCT(lsMarkedString1, language, value);
|
2017-11-30 03:47:29 +00:00
|
|
|
|
2017-12-06 04:39:44 +00:00
|
|
|
struct lsTextDocumentContentChangeEvent {
|
|
|
|
// The range of the document that changed.
|
2017-12-25 08:58:26 +00:00
|
|
|
optional<lsRange> range;
|
2017-12-06 04:39:44 +00:00
|
|
|
// The length of the range that got replaced.
|
2017-12-25 08:58:26 +00:00
|
|
|
optional<int> rangeLength;
|
2017-12-06 04:39:44 +00:00
|
|
|
// The new text of the range/document.
|
|
|
|
std::string text;
|
2017-03-15 07:14:44 +00:00
|
|
|
};
|
2017-12-06 04:39:44 +00:00
|
|
|
MAKE_REFLECT_STRUCT(lsTextDocumentContentChangeEvent, range, rangeLength, text);
|
2017-03-15 07:14:44 +00:00
|
|
|
|
2017-12-06 04:39:44 +00:00
|
|
|
struct lsTextDocumentDidChangeParams {
|
|
|
|
lsVersionedTextDocumentIdentifier textDocument;
|
|
|
|
std::vector<lsTextDocumentContentChangeEvent> contentChanges;
|
2017-03-10 07:06:01 +00:00
|
|
|
};
|
2017-12-06 04:39:44 +00:00
|
|
|
MAKE_REFLECT_STRUCT(lsTextDocumentDidChangeParams,
|
|
|
|
textDocument,
|
|
|
|
contentChanges);
|
2017-03-06 08:48:51 +00:00
|
|
|
|
2017-03-25 21:45:49 +00:00
|
|
|
// Show a message to the user.
|
2017-09-22 01:14:57 +00:00
|
|
|
enum class lsMessageType : int { Error = 1, Warning = 2, Info = 3, Log = 4 };
|
2018-01-30 00:35:01 +00:00
|
|
|
MAKE_REFLECT_TYPE_PROXY(lsMessageType)
|
2017-03-25 21:45:49 +00:00
|
|
|
struct Out_ShowLogMessageParams {
|
2017-03-10 07:06:01 +00:00
|
|
|
lsMessageType type = lsMessageType::Error;
|
|
|
|
std::string message;
|
|
|
|
};
|
2017-03-25 23:58:11 +00:00
|
|
|
MAKE_REFLECT_STRUCT(Out_ShowLogMessageParams, type, message);
|
2017-03-25 21:45:49 +00:00
|
|
|
struct Out_ShowLogMessage : public lsOutMessage<Out_ShowLogMessage> {
|
2017-09-22 01:14:57 +00:00
|
|
|
enum class DisplayType { Show, Log };
|
2017-03-25 21:45:49 +00:00
|
|
|
DisplayType display_type = DisplayType::Show;
|
2017-03-25 23:58:11 +00:00
|
|
|
|
2017-03-25 22:13:19 +00:00
|
|
|
std::string method();
|
2017-03-25 21:45:49 +00:00
|
|
|
Out_ShowLogMessageParams params;
|
2017-03-10 07:06:01 +00:00
|
|
|
};
|
2017-09-22 01:14:57 +00:00
|
|
|
template <typename TVisitor>
|
2017-03-25 21:45:49 +00:00
|
|
|
void Reflect(TVisitor& visitor, Out_ShowLogMessage& value) {
|
2018-01-08 04:10:16 +00:00
|
|
|
REFLECT_MEMBER_START();
|
2017-03-25 21:45:49 +00:00
|
|
|
REFLECT_MEMBER(jsonrpc);
|
2017-05-21 07:43:10 +00:00
|
|
|
std::string method = value.method();
|
|
|
|
REFLECT_MEMBER2("method", method);
|
2017-03-25 21:45:49 +00:00
|
|
|
REFLECT_MEMBER(params);
|
|
|
|
REFLECT_MEMBER_END();
|
2017-04-21 04:50:31 +00:00
|
|
|
}
|
|
|
|
|
2017-10-25 07:12:11 +00:00
|
|
|
struct Out_Progress : public lsOutMessage<Out_Progress> {
|
|
|
|
struct Params {
|
|
|
|
int indexRequestCount = 0;
|
|
|
|
int doIdMapCount = 0;
|
|
|
|
int loadPreviousIndexCount = 0;
|
|
|
|
int onIdMappedCount = 0;
|
|
|
|
int onIndexedCount = 0;
|
2018-01-07 21:06:18 +00:00
|
|
|
int activeThreads = 0;
|
2017-10-25 07:12:11 +00:00
|
|
|
};
|
|
|
|
std::string method = "$cquery/progress";
|
|
|
|
Params params;
|
|
|
|
};
|
|
|
|
MAKE_REFLECT_STRUCT(Out_Progress::Params,
|
|
|
|
indexRequestCount,
|
|
|
|
doIdMapCount,
|
|
|
|
loadPreviousIndexCount,
|
|
|
|
onIdMappedCount,
|
2018-01-07 21:06:18 +00:00
|
|
|
onIndexedCount,
|
|
|
|
activeThreads);
|
2017-10-25 07:12:11 +00:00
|
|
|
MAKE_REFLECT_STRUCT(Out_Progress, jsonrpc, method, params);
|
|
|
|
|
2017-09-22 01:14:57 +00:00
|
|
|
struct Out_CquerySetInactiveRegion
|
|
|
|
: public lsOutMessage<Out_CquerySetInactiveRegion> {
|
2017-05-20 21:45:46 +00:00
|
|
|
struct Params {
|
|
|
|
lsDocumentUri uri;
|
2017-12-12 05:20:29 +00:00
|
|
|
std::vector<lsRange> inactiveRegions;
|
2017-05-20 21:45:46 +00:00
|
|
|
};
|
|
|
|
std::string method = "$cquery/setInactiveRegions";
|
|
|
|
Params params;
|
|
|
|
};
|
|
|
|
MAKE_REFLECT_STRUCT(Out_CquerySetInactiveRegion::Params, uri, inactiveRegions);
|
|
|
|
MAKE_REFLECT_STRUCT(Out_CquerySetInactiveRegion, jsonrpc, method, params);
|
|
|
|
|
2017-05-07 06:56:04 +00:00
|
|
|
struct Out_LocationList : public lsOutMessage<Out_LocationList> {
|
|
|
|
lsRequestId id;
|
2017-12-12 05:20:29 +00:00
|
|
|
std::vector<lsLocation> result;
|
2017-05-07 06:56:04 +00:00
|
|
|
};
|
2017-05-21 07:43:10 +00:00
|
|
|
MAKE_REFLECT_STRUCT(Out_LocationList, jsonrpc, id, result);
|