2018-08-21 05:27:52 +00:00
|
|
|
/* Copyright 2017-2018 ccls Authors
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
==============================================================================*/
|
|
|
|
|
2017-03-05 02:16:23 +00:00
|
|
|
#pragma once
|
|
|
|
|
2018-10-29 04:21:21 +00:00
|
|
|
#include "config.hh"
|
2018-10-28 17:49:31 +00:00
|
|
|
#include "serializer.hh"
|
2018-10-29 04:21:21 +00:00
|
|
|
#include "utils.hh"
|
2017-03-25 20:32:44 +00:00
|
|
|
|
2018-10-28 17:49:31 +00:00
|
|
|
#include <rapidjson/fwd.h>
|
|
|
|
|
2018-12-25 06:20:00 +00:00
|
|
|
#include <chrono>
|
2018-02-22 21:50:46 +00:00
|
|
|
#include <iosfwd>
|
2017-03-05 02:16:23 +00:00
|
|
|
|
2018-10-28 17:49:31 +00:00
|
|
|
namespace ccls {
|
2018-11-03 20:52:43 +00:00
|
|
|
struct RequestId {
|
2019-01-09 07:19:17 +00:00
|
|
|
// 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; }
|
|
|
|
};
|
2018-12-02 23:53:33 +00:00
|
|
|
void Reflect(JsonReader &visitor, RequestId &value);
|
|
|
|
void Reflect(JsonWriter &visitor, RequestId &value);
|
2019-01-09 07:19:17 +00:00
|
|
|
|
|
|
|
struct InMessage {
|
2018-11-03 20:52:43 +00:00
|
|
|
RequestId id;
|
2018-10-28 17:49:31 +00:00
|
|
|
std::string method;
|
|
|
|
std::unique_ptr<char[]> message;
|
|
|
|
std::unique_ptr<rapidjson::Document> document;
|
2018-12-25 06:20:00 +00:00
|
|
|
std::chrono::steady_clock::time_point deadline;
|
|
|
|
std::string backlog_path;
|
2017-03-10 07:06:01 +00:00
|
|
|
};
|
2017-03-05 02:16:23 +00:00
|
|
|
|
2018-11-03 20:52:43 +00:00
|
|
|
enum class ErrorCode {
|
2019-01-09 07:19:17 +00:00
|
|
|
// 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,
|
2017-03-24 07:59:47 +00:00
|
|
|
};
|
|
|
|
|
2018-11-03 20:52:43 +00:00
|
|
|
struct ResponseError {
|
|
|
|
ErrorCode code;
|
2017-03-24 07:59:47 +00:00
|
|
|
std::string message;
|
|
|
|
};
|
|
|
|
|
2019-01-09 07:19:17 +00:00
|
|
|
constexpr char ccls_xref[] = "ccls.xref";
|
|
|
|
constexpr char window_showMessage[] = "window/showMessage";
|
2018-09-29 08:10:56 +00:00
|
|
|
|
2018-11-03 20:52:43 +00:00
|
|
|
struct DocumentUri {
|
|
|
|
static DocumentUri FromPath(const std::string &path);
|
2017-03-11 08:07:32 +00:00
|
|
|
|
2018-12-17 03:53:00 +00:00
|
|
|
bool operator==(const DocumentUri &o) const { return raw_uri == o.raw_uri; }
|
|
|
|
bool operator<(const DocumentUri &o) const { return raw_uri < o.raw_uri; }
|
2017-03-25 23:58:11 +00:00
|
|
|
|
2018-08-09 17:08:14 +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-05 02:16:23 +00:00
|
|
|
|
2018-11-04 18:30:18 +00:00
|
|
|
struct Position {
|
2017-03-10 07:06:01 +00:00
|
|
|
int line = 0;
|
|
|
|
int character = 0;
|
2018-11-04 18:30:18 +00:00
|
|
|
bool operator==(const Position &o) const {
|
2018-04-08 00:10:54 +00:00
|
|
|
return line == o.line && character == o.character;
|
|
|
|
}
|
2018-11-04 18:30:18 +00:00
|
|
|
bool operator<(const Position &o) const {
|
2018-04-08 00:10:54 +00:00
|
|
|
return line != o.line ? line < o.line : character < o.character;
|
|
|
|
}
|
2018-11-16 23:23:26 +00:00
|
|
|
bool operator<=(const Position &o) const {
|
|
|
|
return line != o.line ? line < o.line : character <= o.character;
|
|
|
|
}
|
2018-04-08 00:10:54 +00:00
|
|
|
std::string ToString() const;
|
2017-03-10 07:06:01 +00:00
|
|
|
};
|
2017-03-05 02:16:23 +00:00
|
|
|
|
2017-03-10 07:06:01 +00:00
|
|
|
struct lsRange {
|
2018-11-04 18:30:18 +00:00
|
|
|
Position start;
|
|
|
|
Position end;
|
2018-08-09 17:08:14 +00:00
|
|
|
bool operator==(const lsRange &o) const {
|
2018-04-08 00:10:54 +00:00
|
|
|
return start == o.start && end == o.end;
|
|
|
|
}
|
2018-08-09 17:08:14 +00:00
|
|
|
bool operator<(const lsRange &o) const {
|
2018-04-08 00:10:54 +00:00
|
|
|
return !(start == o.start) ? start < o.start : end < o.end;
|
|
|
|
}
|
2018-11-25 22:55:33 +00:00
|
|
|
bool Includes(const lsRange &o) const {
|
|
|
|
return start <= o.start && o.end <= end;
|
|
|
|
}
|
|
|
|
bool Intersects(const lsRange &o) const {
|
|
|
|
return start < o.end && o.start < end;
|
|
|
|
}
|
2017-03-10 07:06:01 +00:00
|
|
|
};
|
2017-03-05 02:16:23 +00:00
|
|
|
|
2018-11-03 20:52:43 +00:00
|
|
|
struct Location {
|
|
|
|
DocumentUri uri;
|
2017-03-25 22:13:19 +00:00
|
|
|
lsRange range;
|
2018-11-03 20:52:43 +00:00
|
|
|
bool operator==(const Location &o) const {
|
2018-04-08 00:10:54 +00:00
|
|
|
return uri == o.uri && range == o.range;
|
|
|
|
}
|
2018-11-03 20:52:43 +00:00
|
|
|
bool operator<(const Location &o) const {
|
2018-12-17 03:53:00 +00:00
|
|
|
return !(uri == o.uri) ? uri < o.uri : range < o.range;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct LocationLink {
|
|
|
|
std::string targetUri;
|
|
|
|
lsRange targetRange;
|
|
|
|
lsRange targetSelectionRange;
|
|
|
|
explicit operator bool() const { return targetUri.size(); }
|
|
|
|
explicit operator Location() && {
|
|
|
|
return {DocumentUri{std::move(targetUri)}, targetSelectionRange};
|
|
|
|
}
|
|
|
|
bool operator==(const LocationLink &o) const {
|
|
|
|
return targetUri == o.targetUri &&
|
|
|
|
targetSelectionRange == o.targetSelectionRange;
|
|
|
|
}
|
|
|
|
bool operator<(const LocationLink &o) const {
|
|
|
|
return !(targetUri == o.targetUri)
|
|
|
|
? targetUri < o.targetUri
|
|
|
|
: targetSelectionRange < o.targetSelectionRange;
|
2018-04-08 00:10:54 +00:00
|
|
|
}
|
2017-03-10 07:06:01 +00:00
|
|
|
};
|
2017-03-05 02:16:23 +00:00
|
|
|
|
2018-11-03 20:52:43 +00:00
|
|
|
enum class SymbolKind : uint8_t {
|
2018-03-07 21:20:31 +00:00
|
|
|
Unknown = 0,
|
|
|
|
|
|
|
|
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,
|
|
|
|
Object = 19,
|
|
|
|
Key = 20,
|
|
|
|
Null = 21,
|
|
|
|
EnumMember = 22,
|
|
|
|
Struct = 23,
|
|
|
|
Event = 24,
|
|
|
|
Operator = 25,
|
|
|
|
|
|
|
|
// For C++, this is interpreted as "template parameter" (including
|
|
|
|
// non-type template parameters).
|
|
|
|
TypeParameter = 26,
|
|
|
|
|
2018-03-31 03:16:33 +00:00
|
|
|
// ccls extensions
|
2018-03-07 21:20:31 +00:00
|
|
|
// See also https://github.com/Microsoft/language-server-protocol/issues/344
|
|
|
|
// for new SymbolKind clang/Index/IndexSymbol.h clang::index::SymbolKind
|
|
|
|
TypeAlias = 252,
|
|
|
|
Parameter = 253,
|
|
|
|
StaticMethod = 254,
|
|
|
|
Macro = 255,
|
|
|
|
};
|
2018-03-07 03:07:54 +00:00
|
|
|
|
2018-11-03 20:52:43 +00:00
|
|
|
struct SymbolInformation {
|
2018-10-15 08:26:13 +00:00
|
|
|
std::string_view name;
|
2018-11-03 20:52:43 +00:00
|
|
|
SymbolKind kind;
|
|
|
|
Location location;
|
2018-10-15 08:26:13 +00:00
|
|
|
std::optional<std::string_view> containerName;
|
|
|
|
};
|
|
|
|
|
2018-11-03 20:52:43 +00:00
|
|
|
struct TextDocumentIdentifier {
|
|
|
|
DocumentUri uri;
|
2017-03-10 07:06:01 +00:00
|
|
|
};
|
2017-03-05 02:16:23 +00:00
|
|
|
|
2018-11-03 20:52:43 +00:00
|
|
|
struct VersionedTextDocumentIdentifier {
|
|
|
|
DocumentUri uri;
|
2018-01-10 07:57:33 +00:00
|
|
|
// The version number of this document. number | null
|
2018-04-16 19:36:02 +00:00
|
|
|
std::optional<int> version;
|
2017-03-26 06:47:59 +00:00
|
|
|
};
|
|
|
|
|
2018-11-03 20:52:43 +00:00
|
|
|
struct TextEdit {
|
2017-05-21 07:37:53 +00:00
|
|
|
lsRange range;
|
|
|
|
std::string newText;
|
|
|
|
};
|
|
|
|
|
2018-11-03 20:52:43 +00:00
|
|
|
struct TextDocumentItem {
|
|
|
|
DocumentUri uri;
|
2017-03-26 06:47:59 +00:00
|
|
|
std::string languageId;
|
|
|
|
int version;
|
|
|
|
std::string text;
|
|
|
|
};
|
2017-04-14 08:21:03 +00:00
|
|
|
|
2018-10-28 17:49:31 +00:00
|
|
|
struct TextDocumentContentChangeEvent {
|
2017-12-06 04:39:44 +00:00
|
|
|
// The range of the document that changed.
|
2018-03-31 03:16:33 +00:00
|
|
|
std::optional<lsRange> range;
|
2017-12-06 04:39:44 +00:00
|
|
|
// The length of the range that got replaced.
|
2018-03-31 03:16:33 +00:00
|
|
|
std::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
|
|
|
};
|
|
|
|
|
2018-10-28 17:49:31 +00:00
|
|
|
struct TextDocumentDidChangeParam {
|
2018-11-03 20:52:43 +00:00
|
|
|
VersionedTextDocumentIdentifier textDocument;
|
2018-10-28 17:49:31 +00:00
|
|
|
std::vector<TextDocumentContentChangeEvent> contentChanges;
|
2017-03-10 07:06:01 +00:00
|
|
|
};
|
2017-03-06 08:48:51 +00:00
|
|
|
|
2018-10-28 17:49:31 +00:00
|
|
|
struct WorkspaceFolder {
|
2018-11-03 20:52:43 +00:00
|
|
|
DocumentUri uri;
|
2018-10-08 05:02:28 +00:00
|
|
|
std::string name;
|
|
|
|
};
|
|
|
|
|
2018-10-28 17:49:31 +00:00
|
|
|
enum class MessageType : int { Error = 1, Warning = 2, Info = 3, Log = 4 };
|
2018-12-02 23:53:33 +00:00
|
|
|
REFLECT_UNDERLYING(MessageType)
|
2018-04-08 17:32:08 +00:00
|
|
|
|
2018-11-03 20:52:43 +00:00
|
|
|
struct Diagnostic {
|
2019-01-09 07:19:17 +00:00
|
|
|
lsRange range;
|
2018-11-04 18:30:18 +00:00
|
|
|
int severity = 0;
|
2019-01-09 07:19:17 +00:00
|
|
|
int code = 0;
|
|
|
|
std::string source = "ccls";
|
|
|
|
std::string message;
|
2018-11-03 20:52:43 +00:00
|
|
|
std::vector<TextEdit> fixits_;
|
2017-03-10 07:06:01 +00:00
|
|
|
};
|
2017-04-21 04:50:31 +00:00
|
|
|
|
2018-11-03 20:52:43 +00:00
|
|
|
struct ShowMessageParam {
|
2018-10-28 17:49:31 +00:00
|
|
|
MessageType type = MessageType::Error;
|
2019-01-09 07:19:17 +00:00
|
|
|
std::string message;
|
2017-05-07 06:56:04 +00:00
|
|
|
};
|
2018-10-14 06:22:29 +00:00
|
|
|
|
|
|
|
// 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
|
|
|
|
// encounters a c++ declaration.
|
|
|
|
enum class LanguageId { Unknown = -1, C = 0, Cpp = 1, ObjC = 2, ObjCpp = 3 };
|
2018-10-15 08:26:13 +00:00
|
|
|
|
2018-10-28 17:49:31 +00:00
|
|
|
} // namespace ccls
|