Skip to content

Commit

Permalink
Implement textDocument/documentLink
Browse files Browse the repository at this point in the history
  • Loading branch information
MaskRay committed Nov 10, 2019
1 parent 617cdd8 commit 8fa853c
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 115 deletions.
3 changes: 1 addition & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,7 @@ target_sources(ccls PRIVATE
src/messages/textDocument_did.cc
src/messages/textDocument_foldingRange.cc
src/messages/textDocument_formatting.cc
src/messages/textDocument_documentHighlight.cc
src/messages/textDocument_documentSymbol.cc
src/messages/textDocument_document.cc
src/messages/textDocument_hover.cc
src/messages/textDocument_references.cc
src/messages/textDocument_rename.cc
Expand Down
25 changes: 4 additions & 21 deletions src/messages/initialize.cc
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,6 @@ struct lsDocumentOnTypeFormattingOptions {
MAKE_REFLECT_STRUCT(lsDocumentOnTypeFormattingOptions, firstTriggerCharacter,
moreTriggerCharacter);

// Document link options
struct lsDocumentLinkOptions {
// Document links have a resolve provider as well.
bool resolveProvider = false;
};
MAKE_REFLECT_STRUCT(lsDocumentLinkOptions, resolveProvider);

// Save options.
struct lsSaveOptions {
Expand Down Expand Up @@ -132,34 +126,22 @@ struct lsServerCapabilities {
lsCompletionOptions completionProvider;
// The server provides signature help support.
lsSignatureHelpOptions signatureHelpProvider;
// The server provides goto definition support.
bool definitionProvider = true;
// The server provides Goto Type Definition support.
bool typeDefinitionProvider = true;
// The server provides Goto Implementation support.
bool implementationProvider = true;
// The server provides find references support.
bool referencesProvider = true;
// The server provides document highlight support.
bool documentHighlightProvider = true;
// The server provides document symbol support.
bool documentSymbolProvider = true;
// The server provides workspace symbol support.
bool workspaceSymbolProvider = true;
// The server provides code actions.
bool codeActionProvider = true;
// The server provides code lens.
lsCodeLensOptions codeLensProvider;
// The server provides document formatting.
bool documentFormattingProvider = true;
// The server provides document range formatting.
bool documentRangeFormattingProvider = true;
// The server provides document formatting on typing.
lsDocumentOnTypeFormattingOptions documentOnTypeFormattingProvider;
// The server provides rename support.
bool renameProvider = true;
// The server provides document link support.
lsDocumentLinkOptions documentLinkProvider;
struct DocumentLinkOptions {
bool resolveProvider = true;
} documentLinkProvider;
bool foldingRangeProvider = true;
// The server provides execute command support.
struct ExecuteCommandOptions {
Expand All @@ -172,6 +154,7 @@ struct lsServerCapabilities {
} workspaceFolders;
} workspace;
};
MAKE_REFLECT_STRUCT(lsServerCapabilities::DocumentLinkOptions, resolveProvider);
MAKE_REFLECT_STRUCT(lsServerCapabilities::ExecuteCommandOptions, commands);
MAKE_REFLECT_STRUCT(lsServerCapabilities::Workspace::WorkspaceFolders,
supported, changeNotifications);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,116 @@
#include "message_handler.h"
#include "pipeline.hh"
#include "query_utils.h"
using namespace ccls;
using namespace clang;

#include <algorithm>

MAKE_HASHABLE(SymbolIdx, t.usr, t.kind);

namespace ccls {
namespace {
MethodType kMethodType = "textDocument/documentSymbol";
MethodType documentHighlight = "textDocument/documentHighlight",
documentLink = "textDocument/documentLink",
documentSymbol = "textDocument/documentSymbol";

struct lsDocumentHighlight {
enum Kind { Text = 1, Read = 2, Write = 3 };

lsRange range;
int kind = 1;

// ccls extension
Role role = Role::None;

bool operator<(const lsDocumentHighlight &o) const {
return !(range == o.range) ? range < o.range : kind < o.kind;
}
};
MAKE_REFLECT_STRUCT(lsDocumentHighlight, range, kind, role);

struct In_TextDocumentDocumentHighlight : public RequestMessage {
MethodType GetMethodType() const override { return documentHighlight; }
lsTextDocumentPositionParams params;
};
MAKE_REFLECT_STRUCT(In_TextDocumentDocumentHighlight, id, params);
REGISTER_IN_MESSAGE(In_TextDocumentDocumentHighlight);

struct Handler_TextDocumentDocumentHighlight
: BaseMessageHandler<In_TextDocumentDocumentHighlight> {
MethodType GetMethodType() const override { return documentHighlight; }
void Run(In_TextDocumentDocumentHighlight *request) override {
int file_id;
QueryFile *file;
if (!FindFileOrFail(db, project, request->id,
request->params.textDocument.uri.GetPath(), &file,
&file_id))
return;

WorkingFile *wfile = working_files->GetFileByFilename(file->def->path);
std::vector<lsDocumentHighlight> result;

std::vector<SymbolRef> syms =
FindSymbolsAtLocation(wfile, file, request->params.position, true);
for (auto [sym, refcnt] : file->symbol2refcnt) {
if (refcnt <= 0)
continue;
Usr usr = sym.usr;
SymbolKind kind = sym.kind;
if (std::none_of(syms.begin(), syms.end(), [&](auto &sym1) {
return usr == sym1.usr && kind == sym1.kind;
}))
continue;
if (auto loc = GetLsLocation(db, working_files, sym, file_id)) {
lsDocumentHighlight highlight;
highlight.range = loc->range;
if (sym.role & Role::Write)
highlight.kind = lsDocumentHighlight::Write;
else if (sym.role & Role::Read)
highlight.kind = lsDocumentHighlight::Read;
else
highlight.kind = lsDocumentHighlight::Text;
highlight.role = sym.role;
result.push_back(highlight);
}
}
std::sort(result.begin(), result.end());
pipeline::Reply(request->id, result);
}
};
REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDocumentHighlight);

struct In_textDocumentDocumentLink : public RequestMessage {
MethodType GetMethodType() const override { return documentLink; }
lsTextDocumentPositionParams params;
};
MAKE_REFLECT_STRUCT(In_textDocumentDocumentLink, id, params);
REGISTER_IN_MESSAGE(In_textDocumentDocumentLink);

struct lsDocumentLink {
lsRange range;
lsDocumentUri target;
};
MAKE_REFLECT_STRUCT(lsDocumentLink, range, target);

struct Handler_textDocumentDocumentLink
: BaseMessageHandler<In_textDocumentDocumentLink> {
MethodType GetMethodType() const override { return documentLink; }
void Run(In_textDocumentDocumentLink *request) override {
QueryFile *file;
if (!FindFileOrFail(db, project, request->id,
request->params.textDocument.uri.GetPath(), &file))
return;

std::vector<lsDocumentLink> result;
for (const IndexInclude &include : file->def->includes)
result.push_back({lsRange{{include.line, 0}, {include.line + 1, 0}},
lsDocumentUri::FromPath(include.resolved_path)});
pipeline::Reply(request->id, result);
}
};
REGISTER_MESSAGE_HANDLER(Handler_textDocumentDocumentLink);

struct In_TextDocumentDocumentSymbol : public RequestMessage {
MethodType GetMethodType() const override { return kMethodType; }
struct In_textDocumentDocumentSymbol : public RequestMessage {
MethodType GetMethodType() const override { return documentSymbol; }
struct Params {
lsTextDocumentIdentifier textDocument;
// false: outline; true: all symbols
Expand All @@ -23,10 +123,10 @@ struct In_TextDocumentDocumentSymbol : public RequestMessage {
int endLine = -1;
} params;
};
MAKE_REFLECT_STRUCT(In_TextDocumentDocumentSymbol::Params, textDocument, all,
MAKE_REFLECT_STRUCT(In_textDocumentDocumentSymbol::Params, textDocument, all,
startLine, endLine);
MAKE_REFLECT_STRUCT(In_TextDocumentDocumentSymbol, id, params);
REGISTER_IN_MESSAGE(In_TextDocumentDocumentSymbol);
MAKE_REFLECT_STRUCT(In_textDocumentDocumentSymbol, id, params);
REGISTER_IN_MESSAGE(In_textDocumentDocumentSymbol);

struct lsDocumentSymbol {
std::string name;
Expand Down Expand Up @@ -56,10 +156,10 @@ bool Ignore(const QueryVar::Def *def) {
return !def || def->is_local();
}

struct Handler_TextDocumentDocumentSymbol
: BaseMessageHandler<In_TextDocumentDocumentSymbol> {
MethodType GetMethodType() const override { return kMethodType; }
void Run(In_TextDocumentDocumentSymbol *request) override {
struct Handler_textDocumentDocumentSymbol
: BaseMessageHandler<In_textDocumentDocumentSymbol> {
MethodType GetMethodType() const override { return documentSymbol; }
void Run(In_textDocumentDocumentSymbol *request) override {
auto &params = request->params;

QueryFile *file;
Expand Down Expand Up @@ -180,5 +280,6 @@ struct Handler_TextDocumentDocumentSymbol
}
}
};
REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDocumentSymbol);
REGISTER_MESSAGE_HANDLER(Handler_textDocumentDocumentSymbol);
} // namespace
} // namespace ccls
79 changes: 0 additions & 79 deletions src/messages/textDocument_documentHighlight.cc

This file was deleted.

0 comments on commit 8fa853c

Please sign in to comment.