mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-28 02:21:57 +00:00
ab48663ca0
* WorkingFiles::files : vector -> unordered_map * Add timestamp to WorkingFile * Rename "comp-preload" thread to "preamble" * Rename CompletionManager to SemaManager as it is used by "diag" "comp" "preamble" * Rename clang_complete.* to sema_manager.* * Merge SemaManager::{preloads,sessions} * Add initialization option session.maxNum * In DiagnosticMain, if an included file was modified, cancel the DiagTask and create a PreambleTask instead. The task sets `from_diag` so as to trigger immediate DiagTask after the preamble is built.
278 lines
8.4 KiB
C++
278 lines
8.4 KiB
C++
/* 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.
|
|
==============================================================================*/
|
|
|
|
#pragma once
|
|
|
|
#include "lsp.hh"
|
|
#include "query.hh"
|
|
|
|
#include <functional>
|
|
#include <memory>
|
|
#include <optional>
|
|
#include <vector>
|
|
|
|
namespace ccls {
|
|
struct SemaManager;
|
|
struct VFS;
|
|
struct IncludeComplete;
|
|
struct Project;
|
|
struct WorkingFile;
|
|
struct WorkingFiles;
|
|
|
|
namespace pipeline {
|
|
void Reply(RequestId id, const std::function<void(Writer &)> &fn);
|
|
void ReplyError(RequestId id, const std::function<void(Writer &)> &fn);
|
|
}
|
|
|
|
struct CodeActionParam {
|
|
TextDocumentIdentifier textDocument;
|
|
lsRange range;
|
|
struct Context {
|
|
std::vector<Diagnostic> diagnostics;
|
|
} context;
|
|
};
|
|
struct EmptyParam {};
|
|
struct DidOpenTextDocumentParam {
|
|
TextDocumentItem textDocument;
|
|
};
|
|
struct RenameParam {
|
|
TextDocumentIdentifier textDocument;
|
|
Position position;
|
|
std::string newName;
|
|
};
|
|
struct TextDocumentParam {
|
|
TextDocumentIdentifier textDocument;
|
|
};
|
|
struct TextDocumentPositionParam {
|
|
TextDocumentIdentifier textDocument;
|
|
Position position;
|
|
};
|
|
struct TextDocumentEdit {
|
|
VersionedTextDocumentIdentifier textDocument;
|
|
std::vector<TextEdit> edits;
|
|
};
|
|
MAKE_REFLECT_STRUCT(TextDocumentEdit, textDocument, edits);
|
|
struct WorkspaceEdit {
|
|
std::vector<TextDocumentEdit> documentChanges;
|
|
};
|
|
MAKE_REFLECT_STRUCT(WorkspaceEdit, documentChanges);
|
|
|
|
// completion
|
|
enum class CompletionTriggerKind {
|
|
Invoked = 1,
|
|
TriggerCharacter = 2,
|
|
TriggerForIncompleteCompletions = 3,
|
|
};
|
|
struct CompletionContext {
|
|
CompletionTriggerKind triggerKind = CompletionTriggerKind::Invoked;
|
|
std::optional<std::string> triggerCharacter;
|
|
};
|
|
struct CompletionParam : TextDocumentPositionParam {
|
|
CompletionContext context;
|
|
};
|
|
enum class CompletionItemKind {
|
|
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,
|
|
Reference = 18,
|
|
Folder = 19,
|
|
EnumMember = 20,
|
|
Constant = 21,
|
|
Struct = 22,
|
|
Event = 23,
|
|
Operator = 24,
|
|
TypeParameter = 25,
|
|
};
|
|
enum class InsertTextFormat {
|
|
PlainText = 1,
|
|
Snippet = 2
|
|
};
|
|
struct CompletionItem {
|
|
std::string label;
|
|
CompletionItemKind kind = CompletionItemKind::Text;
|
|
std::string detail;
|
|
std::string documentation;
|
|
std::string sortText;
|
|
std::string filterText;
|
|
InsertTextFormat insertTextFormat = InsertTextFormat::PlainText;
|
|
TextEdit textEdit;
|
|
std::vector<TextEdit> additionalTextEdits;
|
|
|
|
std::vector<std::string> parameters_;
|
|
int score_;
|
|
unsigned priority_;
|
|
bool use_angle_brackets_ = false;
|
|
};
|
|
|
|
// formatting
|
|
struct FormattingOptions {
|
|
int tabSize;
|
|
bool insertSpaces;
|
|
};
|
|
struct DocumentFormattingParam {
|
|
TextDocumentIdentifier textDocument;
|
|
FormattingOptions options;
|
|
};
|
|
struct DocumentOnTypeFormattingParam {
|
|
TextDocumentIdentifier textDocument;
|
|
Position position;
|
|
std::string ch;
|
|
FormattingOptions options;
|
|
};
|
|
struct DocumentRangeFormattingParam {
|
|
TextDocumentIdentifier textDocument;
|
|
lsRange range;
|
|
FormattingOptions options;
|
|
};
|
|
|
|
// workspace
|
|
enum class FileChangeType {
|
|
Created = 1,
|
|
Changed = 2,
|
|
Deleted = 3,
|
|
};
|
|
struct DidChangeWatchedFilesParam {
|
|
struct Event {
|
|
DocumentUri uri;
|
|
FileChangeType type;
|
|
};
|
|
std::vector<Event> changes;
|
|
};
|
|
struct DidChangeWorkspaceFoldersParam {
|
|
struct Event {
|
|
std::vector<WorkspaceFolder> added, removed;
|
|
} event;
|
|
};
|
|
struct WorkspaceSymbolParam {
|
|
std::string query;
|
|
|
|
// ccls extensions
|
|
std::vector<std::string> folders;
|
|
};
|
|
MAKE_REFLECT_STRUCT(WorkspaceFolder, uri, name);
|
|
|
|
MAKE_REFLECT_TYPE_PROXY(ErrorCode);
|
|
MAKE_REFLECT_STRUCT(ResponseError, code, message);
|
|
MAKE_REFLECT_STRUCT(Position, line, character);
|
|
MAKE_REFLECT_STRUCT(lsRange, start, end);
|
|
MAKE_REFLECT_STRUCT(Location, uri, range);
|
|
MAKE_REFLECT_TYPE_PROXY(SymbolKind);
|
|
MAKE_REFLECT_STRUCT(TextDocumentIdentifier, uri);
|
|
MAKE_REFLECT_STRUCT(TextDocumentItem, uri, languageId, version, text);
|
|
MAKE_REFLECT_STRUCT(TextEdit, range, newText);
|
|
MAKE_REFLECT_STRUCT(VersionedTextDocumentIdentifier, uri, version);
|
|
MAKE_REFLECT_STRUCT(Diagnostic, range, severity, code, source, message);
|
|
MAKE_REFLECT_STRUCT(ShowMessageParam, type, message);
|
|
MAKE_REFLECT_TYPE_PROXY(LanguageId);
|
|
|
|
struct ReplyOnce {
|
|
RequestId id;
|
|
template <typename Res> void operator()(Res &&result) const {
|
|
if (id.Valid())
|
|
pipeline::Reply(id, [&](Writer &w) { Reflect(w, result); });
|
|
}
|
|
void Error(ErrorCode code, std::string message) const {
|
|
ResponseError err{code, std::move(message)};
|
|
if (id.Valid())
|
|
pipeline::ReplyError(id, [&](Writer &w) { Reflect(w, err); });
|
|
}
|
|
};
|
|
|
|
struct MessageHandler {
|
|
SemaManager *manager = nullptr;
|
|
DB *db = nullptr;
|
|
IncludeComplete *include_complete = nullptr;
|
|
Project *project = nullptr;
|
|
VFS *vfs = nullptr;
|
|
WorkingFiles *wfiles = nullptr;
|
|
|
|
llvm::StringMap<std::function<void(Reader &)>> method2notification;
|
|
llvm::StringMap<std::function<void(Reader &, ReplyOnce &)>> method2request;
|
|
|
|
MessageHandler();
|
|
void Run(InMessage &msg);
|
|
QueryFile *FindFile(ReplyOnce &reply, const std::string &path,
|
|
int *out_file_id = nullptr);
|
|
|
|
private:
|
|
void Bind(const char *method, void (MessageHandler::*handler)(Reader &));
|
|
template <typename Param>
|
|
void Bind(const char *method, void (MessageHandler::*handler)(Param &));
|
|
void Bind(const char *method,
|
|
void (MessageHandler::*handler)(Reader &, ReplyOnce &));
|
|
template <typename Param>
|
|
void Bind(const char *method,
|
|
void (MessageHandler::*handler)(Param &, ReplyOnce &));
|
|
|
|
void ccls_call(Reader &, ReplyOnce &);
|
|
void ccls_fileInfo(TextDocumentParam &, ReplyOnce &);
|
|
void ccls_info(EmptyParam &, ReplyOnce &);
|
|
void ccls_inheritance(Reader &, ReplyOnce &);
|
|
void ccls_member(Reader &, ReplyOnce &);
|
|
void ccls_navigate(Reader &, ReplyOnce &);
|
|
void ccls_reload(Reader &);
|
|
void ccls_vars(Reader &, ReplyOnce &);
|
|
void exit(EmptyParam &);
|
|
void initialize(Reader &, ReplyOnce &);
|
|
void shutdown(EmptyParam &, ReplyOnce &);
|
|
void textDocument_codeAction(CodeActionParam &, ReplyOnce &);
|
|
void textDocument_codeLens(TextDocumentParam &, ReplyOnce &);
|
|
void textDocument_completion(CompletionParam &, ReplyOnce &);
|
|
void textDocument_definition(TextDocumentPositionParam &, ReplyOnce &);
|
|
void textDocument_didChange(TextDocumentDidChangeParam &);
|
|
void textDocument_didClose(TextDocumentParam &);
|
|
void textDocument_didOpen(DidOpenTextDocumentParam &);
|
|
void textDocument_didSave(TextDocumentParam &);
|
|
void textDocument_documentHighlight(TextDocumentPositionParam &, ReplyOnce &);
|
|
void textDocument_documentLink(TextDocumentParam &, ReplyOnce &);
|
|
void textDocument_documentSymbol(Reader &, ReplyOnce &);
|
|
void textDocument_foldingRange(TextDocumentParam &, ReplyOnce &);
|
|
void textDocument_formatting(DocumentFormattingParam &, ReplyOnce &);
|
|
void textDocument_hover(TextDocumentPositionParam &, ReplyOnce &);
|
|
void textDocument_implementation(TextDocumentPositionParam &, ReplyOnce &);
|
|
void textDocument_onTypeFormatting(DocumentOnTypeFormattingParam &,
|
|
ReplyOnce &);
|
|
void textDocument_rangeFormatting(DocumentRangeFormattingParam &,
|
|
ReplyOnce &);
|
|
void textDocument_references(Reader &, ReplyOnce &);
|
|
void textDocument_rename(RenameParam &, ReplyOnce &);
|
|
void textDocument_signatureHelp(TextDocumentPositionParam &, ReplyOnce &);
|
|
void textDocument_typeDefinition(TextDocumentPositionParam &, ReplyOnce &);
|
|
void workspace_didChangeConfiguration(EmptyParam &);
|
|
void workspace_didChangeWatchedFiles(DidChangeWatchedFilesParam &);
|
|
void workspace_didChangeWorkspaceFolders(DidChangeWorkspaceFoldersParam &);
|
|
void workspace_executeCommand(Reader &, ReplyOnce &);
|
|
void workspace_symbol(WorkspaceSymbolParam &, ReplyOnce &);
|
|
};
|
|
|
|
void EmitSkippedRanges(WorkingFile *wfile, QueryFile &file);
|
|
|
|
void EmitSemanticHighlight(DB *db, WorkingFile *wfile, QueryFile &file);
|
|
} // namespace ccls
|