Skip to content

Commit

Permalink
Add pipeline::{Notify,Reply,ReplyError} and simplify message handling
Browse files Browse the repository at this point in the history
Delete method.{cc,h}
Rename $ccls/setSkippedRanges to $ccls/publishSkippedRanges
Rename $ccls/publishSemanticHighlighting to $ccls/publishSemanticHighlight; stableId -> id
  • Loading branch information
MaskRay committed Nov 10, 2019
1 parent 4a1eea7 commit bc4dc67
Show file tree
Hide file tree
Showing 48 changed files with 715 additions and 1,096 deletions.
3 changes: 0 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,6 @@ target_sources(ccls PRIVATE
src/main.cc
src/include_complete.cc
src/indexer.cc
src/method.cc
src/log.cc
src/lsp.cc
src/match.cc
Expand Down Expand Up @@ -225,12 +224,10 @@ target_sources(ccls PRIVATE
src/messages/textDocument_documentHighlight.cc
src/messages/textDocument_documentSymbol.cc
src/messages/textDocument_hover.cc
src/messages/textDocument_implementation.cc
src/messages/textDocument_references.cc
src/messages/textDocument_rename.cc
src/messages/textDocument_signatureHelp.cc
src/messages/textDocument_typeDefinition.cc
src/messages/workspace_did.cc
src/messages/workspace_didChangeWatchedFiles.cc
src/messages/workspace_symbol.cc
)
2 changes: 1 addition & 1 deletion src/clang_complete.hh
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@

#include "clang_tu.hh"
#include "lru_cache.h"
#include "lsp.h"
#include "lsp_completion.h"
#include "lsp_diagnostic.h"
#include "project.h"
#include "threaded_queue.h"
#include "working_files.h"
Expand Down
15 changes: 9 additions & 6 deletions src/hierarchy.hh
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,22 @@
#include <queue>

template <typename Node>
void FlattenHierarchy(const Node &root, Out_LocationList &out) {
std::vector<lsLocation> FlattenHierarchy(const std::optional<Node> &root) {
if (!root)
return {};
std::vector<lsLocation> ret;
std::queue<const Node *> q;
for (auto &entry : root.children)
for (auto &entry : root->children)
q.push(&entry);
while (q.size()) {
auto *entry = q.front();
q.pop();
if (entry->location.uri.raw_uri.size())
out.result.push_back({entry->location});
ret.push_back({entry->location});
for (auto &entry1 : entry->children)
q.push(&entry1);
}
std::sort(out.result.begin(), out.result.end());
out.result.erase(std::unique(out.result.begin(), out.result.end()),
out.result.end());
std::sort(ret.begin(), ret.end());
ret.erase(std::unique(ret.begin(), ret.end()), ret.end());
return ret;
}
1 change: 0 additions & 1 deletion src/indexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#pragma once

#include "lsp.h"
#include "lsp_diagnostic.h"
#include "maybe.h"
#include "position.h"
#include "serializer.h"
Expand Down
66 changes: 36 additions & 30 deletions src/lsp.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,46 @@
#include "log.hh"
#include "serializers/json.h"

#include <rapidjson/writer.h>
#include <rapidjson/document.h>

#include <algorithm>
#include <stdio.h>

MethodType kMethodType_Exit = "exit";

void Reflect(Reader &visitor, lsRequestId &value) {
if (visitor.IsInt64()) {
value.type = lsRequestId::kInt;
value.value = int(visitor.GetInt64());
} else if (visitor.IsInt()) {
value.type = lsRequestId::kInt;
value.value = visitor.GetInt();
} else if (visitor.IsString()) {
value.type = lsRequestId::kString;
value.value = atoll(visitor.GetString());
} else {
value.type = lsRequestId::kNone;
value.value = -1;
}
}

void Reflect(Writer &visitor, lsRequestId &value) {
switch (value.type) {
case lsRequestId::kNone:
visitor.Null();
break;
case lsRequestId::kInt:
visitor.Int(value.value);
break;
case lsRequestId::kString:
auto s = std::to_string(value.value);
visitor.String(s.c_str(), s.length());
break;
}
}

InMessage::~InMessage() {}

MessageRegistry *MessageRegistry::instance_ = nullptr;

lsTextDocumentIdentifier
Expand Down Expand Up @@ -134,29 +169,6 @@ MessageRegistry *MessageRegistry::instance() {
return instance_;
}

lsBaseOutMessage::~lsBaseOutMessage() = default;

void lsBaseOutMessage::Write(std::ostream &out) {
rapidjson::StringBuffer output;
rapidjson::Writer<rapidjson::StringBuffer> writer(output);
JsonWriter json_writer{&writer};
ReflectWriter(json_writer);

out << "Content-Length: " << output.GetSize() << "\r\n\r\n"
<< output.GetString();
out.flush();
}

void lsResponseError::Write(Writer &visitor) {
auto &value = *this;
int code2 = static_cast<int>(this->code);

visitor.StartObject();
REFLECT_MEMBER2("code", code2);
REFLECT_MEMBER(message);
visitor.EndObject();
}

lsDocumentUri lsDocumentUri::FromPath(const std::string &path) {
lsDocumentUri result;
result.SetPath(path);
Expand Down Expand Up @@ -261,9 +273,3 @@ void Reflect(Writer &visitor, lsMarkedString &value) {
Reflect(visitor, value.value);
}
}

std::string Out_ShowLogMessage::method() {
if (display_type == DisplayType::Log)
return "window/logMessage";
return "window/showMessage";
}
150 changes: 96 additions & 54 deletions src/lsp.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,42 @@
#pragma once

#include "config.h"
#include "method.h"
#include "serializer.h"
#include "utils.h"

#include <iosfwd>
#include <unordered_map>

using MethodType = const char *;
extern MethodType kMethodType_Exit;

struct lsRequestId {
// The client can send the request id as an int or a string. We should output
// the same format we received.
enum Type { kNone, kInt, kString };
Type type = kNone;

int value = -1;

bool Valid() const { return type != kNone; }
};
void Reflect(Reader &visitor, lsRequestId &value);
void Reflect(Writer &visitor, lsRequestId &value);

struct InMessage {
virtual ~InMessage();

virtual MethodType GetMethodType() const = 0;
virtual lsRequestId GetRequestId() const { return {}; }
};

struct NotificationMessage : InMessage {};

struct RequestMessage : public InMessage {
lsRequestId id;
lsRequestId GetRequestId() const override { return id; }
};

#define REGISTER_IN_MESSAGE(type) \
static MessageRegistryRegister<type> type##message_handler_instance_;

Expand Down Expand Up @@ -41,45 +70,38 @@ template <typename T> struct MessageRegistryRegister {
}
};

struct lsBaseOutMessage {
virtual ~lsBaseOutMessage();
virtual void ReflectWriter(Writer &) = 0;

// Send the message to the language client by writing it to stdout.
void Write(std::ostream &out);
};

template <typename TDerived> struct lsOutMessage : lsBaseOutMessage {
// All derived types need to reflect on the |jsonrpc| member.
std::string jsonrpc = "2.0";

void ReflectWriter(Writer &writer) override {
Reflect(writer, static_cast<TDerived &>(*this));
}
enum class lsErrorCodes {
// Defined by JSON RPC
ParseError = -32700,
InvalidRequest = -32600,
MethodNotFound = -32601,
InvalidParams = -32602,
InternalError = -32603,
serverErrorStart = -32099,
serverErrorEnd = -32000,
ServerNotInitialized = -32002,
UnknownErrorCode = -32001,

// Defined by the protocol.
RequestCancelled = -32800,
};
MAKE_REFLECT_TYPE_PROXY(lsErrorCodes);

struct lsResponseError {
enum class lsErrorCodes : int {
ParseError = -32700,
InvalidRequest = -32600,
MethodNotFound = -32601,
InvalidParams = -32602,
InternalError = -32603,
serverErrorStart = -32099,
serverErrorEnd = -32000,
ServerNotInitialized = -32002,
UnknownErrorCode = -32001,
RequestCancelled = -32800,
};

// A number indicating the error type that occurred.
lsErrorCodes code;
// Short description.

// A string providing a short description of the error.
std::string message;

void Write(Writer &visitor);
// A Primitive or Structured value that contains additional
// information about the error. Can be omitted.
// std::optional<D> data;
};
MAKE_REFLECT_STRUCT(lsResponseError, code, message);

constexpr std::string_view ccls_xref("ccls.xref");
constexpr char ccls_xref[] = "ccls.xref";
constexpr char window_showMessage[] = "window/showMessage";

/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -305,35 +327,55 @@ MAKE_REFLECT_STRUCT(lsWorkspaceFolder, uri, name);
enum class lsMessageType : int { Error = 1, Warning = 2, Info = 3, Log = 4 };
MAKE_REFLECT_TYPE_PROXY(lsMessageType)

struct Out_ShowLogMessageParams {
lsMessageType type = lsMessageType::Error;
std::string message;
enum class lsDiagnosticSeverity {
// Reports an error.
Error = 1,
// Reports a warning.
Warning = 2,
// Reports an information.
Information = 3,
// Reports a hint.
Hint = 4
};
MAKE_REFLECT_STRUCT(Out_ShowLogMessageParams, type, message);
MAKE_REFLECT_TYPE_PROXY(lsDiagnosticSeverity);

struct lsDiagnostic {
// The range at which the message applies.
lsRange range;

struct Out_ShowLogMessage : public lsOutMessage<Out_ShowLogMessage> {
enum class DisplayType { Show, Log };
DisplayType display_type = DisplayType::Show;
// The diagnostic's severity. Can be omitted. If omitted it is up to the
// client to interpret diagnostics as error, warning, info or hint.
std::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 = "ccls";

// The diagnostic's message.
std::string message;

std::string method();
Out_ShowLogMessageParams params;
// Non-serialized set of fixits.
std::vector<lsTextEdit> fixits_;
};
MAKE_REFLECT_STRUCT(lsDiagnostic, range, severity, source, message);

template <typename TVisitor>
void Reflect(TVisitor &visitor, Out_ShowLogMessage &value) {
REFLECT_MEMBER_START();
REFLECT_MEMBER(jsonrpc);
std::string method = value.method();
REFLECT_MEMBER2("method", method);
REFLECT_MEMBER(params);
REFLECT_MEMBER_END();
}
struct lsPublishDiagnosticsParams {
// The URI for which diagnostic information is reported.
lsDocumentUri uri;

struct Out_LocationList : public lsOutMessage<Out_LocationList> {
lsRequestId id;
std::vector<lsLocation> result;
// An array of diagnostic information items.
std::vector<lsDiagnostic> diagnostics;
};
MAKE_REFLECT_STRUCT(lsPublishDiagnosticsParams, uri, diagnostics);

struct lsShowMessageParams {
lsMessageType type = lsMessageType::Error;
std::string message;
};
MAKE_REFLECT_STRUCT(Out_LocationList, jsonrpc, id, result);
MAKE_REFLECT_STRUCT(lsShowMessageParams, type, message);

// Used to identify the language at a file level. The ordering is important, as
// a file previously identified as `C`, will be changed to `Cpp` if it
Expand Down
Loading

0 comments on commit bc4dc67

Please sign in to comment.