2017-05-16 17:38:59 +08:00
|
|
|
//===--- ClangdLSPServer.cpp - LSP server ------------------------*- C++-*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===---------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "ClangdLSPServer.h"
|
|
|
|
#include "JSONRPCDispatcher.h"
|
|
|
|
|
[clangd] Handle clangd.applyFix server-side
Summary:
When the user selects a fix-it (or any code action with commands), it is
possible to let the client forward the selected command to the server.
When the clangd.applyFix command is handled on the server, it can send a
workspace/applyEdit request to the client. This has the advantage that
the client doesn't explicitly have to know how to handle
clangd.applyFix. Therefore, the code to handle clangd.applyFix in the VS
Code extension (and any other Clangd client) is not required anymore.
Reviewers: ilya-biryukov, sammccall, Nebiroth, hokein
Reviewed By: hokein
Subscribers: ioeric, hokein, rwols, puremourning, bkramer, ilya-biryukov
Tags: #clang-tools-extra
Differential Revision: https://reviews.llvm.org/D39276
llvm-svn: 317322
2017-11-03 21:39:15 +08:00
|
|
|
#include "llvm/Support/FormatVariadic.h"
|
|
|
|
|
2017-05-16 17:38:59 +08:00
|
|
|
using namespace clang::clangd;
|
|
|
|
using namespace clang;
|
|
|
|
|
2017-05-16 22:40:30 +08:00
|
|
|
namespace {
|
|
|
|
|
[clangd] Handle clangd.applyFix server-side
Summary:
When the user selects a fix-it (or any code action with commands), it is
possible to let the client forward the selected command to the server.
When the clangd.applyFix command is handled on the server, it can send a
workspace/applyEdit request to the client. This has the advantage that
the client doesn't explicitly have to know how to handle
clangd.applyFix. Therefore, the code to handle clangd.applyFix in the VS
Code extension (and any other Clangd client) is not required anymore.
Reviewers: ilya-biryukov, sammccall, Nebiroth, hokein
Reviewed By: hokein
Subscribers: ioeric, hokein, rwols, puremourning, bkramer, ilya-biryukov
Tags: #clang-tools-extra
Differential Revision: https://reviews.llvm.org/D39276
llvm-svn: 317322
2017-11-03 21:39:15 +08:00
|
|
|
std::vector<TextEdit>
|
2017-05-16 22:40:30 +08:00
|
|
|
replacementsToEdits(StringRef Code,
|
|
|
|
const std::vector<tooling::Replacement> &Replacements) {
|
|
|
|
// Turn the replacements into the format specified by the Language Server
|
Adds a json::Expr type to represent intermediate JSON expressions.
Summary:
This form can be created with a nice clang-format-friendly literal syntax,
and gets escaping right. It knows how to call unparse() on our Protocol types.
All the places where we pass around JSON internally now use this type.
Object properties are sorted (stored as std::map) and so serialization is
canonicalized, with optional prettyprinting (triggered by a -pretty flag).
This makes the lit tests much nicer to read and somewhat nicer to debug.
(Unfortunately the completion tests use CHECK-DAG, which only has
line-granularity, so pretty-printing is disabled there. In future we
could make completion ordering deterministic, or switch to unittests).
Compared to the current approach, it has some efficiencies like avoiding copies
of string literals used as object keys, but is probably slower overall.
I think the code/test quality benefits are worth it.
This patch doesn't attempt to do anything about JSON *parsing*.
It takes direction from the proposal in this doc[1], but is limited in scope
and visibility, for now.
I am of half a mind just to use Expr as the target of a parser, and maybe do a
little string deduplication, but not bother with clever memory allocation.
That would be simple, and fast enough for clangd...
[1] https://docs.google.com/document/d/1OEF9IauWwNuSigZzvvbjc1cVS1uGHRyGTXaoy3DjqM4/edit
+cc d0k so he can tell me not to use std::map.
Reviewers: ioeric, malaperle
Subscribers: bkramer, ilya-biryukov, mgorny, klimek
Differential Revision: https://reviews.llvm.org/D39435
llvm-svn: 317486
2017-11-06 23:40:30 +08:00
|
|
|
// Protocol. Fuse them into one big JSON array.
|
|
|
|
std::vector<TextEdit> Edits;
|
2017-05-16 22:40:30 +08:00
|
|
|
for (auto &R : Replacements) {
|
|
|
|
Range ReplacementRange = {
|
|
|
|
offsetToPosition(Code, R.getOffset()),
|
|
|
|
offsetToPosition(Code, R.getOffset() + R.getLength())};
|
[clangd] Handle clangd.applyFix server-side
Summary:
When the user selects a fix-it (or any code action with commands), it is
possible to let the client forward the selected command to the server.
When the clangd.applyFix command is handled on the server, it can send a
workspace/applyEdit request to the client. This has the advantage that
the client doesn't explicitly have to know how to handle
clangd.applyFix. Therefore, the code to handle clangd.applyFix in the VS
Code extension (and any other Clangd client) is not required anymore.
Reviewers: ilya-biryukov, sammccall, Nebiroth, hokein
Reviewed By: hokein
Subscribers: ioeric, hokein, rwols, puremourning, bkramer, ilya-biryukov
Tags: #clang-tools-extra
Differential Revision: https://reviews.llvm.org/D39276
llvm-svn: 317322
2017-11-03 21:39:15 +08:00
|
|
|
Edits.push_back({ReplacementRange, R.getReplacementText()});
|
2017-05-16 22:40:30 +08:00
|
|
|
}
|
|
|
|
return Edits;
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
2017-10-12 21:29:58 +08:00
|
|
|
void ClangdLSPServer::onInitialize(Ctx C, InitializeParams &Params) {
|
Adds a json::Expr type to represent intermediate JSON expressions.
Summary:
This form can be created with a nice clang-format-friendly literal syntax,
and gets escaping right. It knows how to call unparse() on our Protocol types.
All the places where we pass around JSON internally now use this type.
Object properties are sorted (stored as std::map) and so serialization is
canonicalized, with optional prettyprinting (triggered by a -pretty flag).
This makes the lit tests much nicer to read and somewhat nicer to debug.
(Unfortunately the completion tests use CHECK-DAG, which only has
line-granularity, so pretty-printing is disabled there. In future we
could make completion ordering deterministic, or switch to unittests).
Compared to the current approach, it has some efficiencies like avoiding copies
of string literals used as object keys, but is probably slower overall.
I think the code/test quality benefits are worth it.
This patch doesn't attempt to do anything about JSON *parsing*.
It takes direction from the proposal in this doc[1], but is limited in scope
and visibility, for now.
I am of half a mind just to use Expr as the target of a parser, and maybe do a
little string deduplication, but not bother with clever memory allocation.
That would be simple, and fast enough for clangd...
[1] https://docs.google.com/document/d/1OEF9IauWwNuSigZzvvbjc1cVS1uGHRyGTXaoy3DjqM4/edit
+cc d0k so he can tell me not to use std::map.
Reviewers: ioeric, malaperle
Subscribers: bkramer, ilya-biryukov, mgorny, klimek
Differential Revision: https://reviews.llvm.org/D39435
llvm-svn: 317486
2017-11-06 23:40:30 +08:00
|
|
|
C.reply(json::obj{
|
2017-11-07 23:49:35 +08:00
|
|
|
{{"capabilities",
|
|
|
|
json::obj{
|
|
|
|
{"textDocumentSync", 1},
|
|
|
|
{"documentFormattingProvider", true},
|
|
|
|
{"documentRangeFormattingProvider", true},
|
|
|
|
{"documentOnTypeFormattingProvider",
|
|
|
|
json::obj{
|
|
|
|
{"firstTriggerCharacter", "}"},
|
|
|
|
{"moreTriggerCharacter", {}},
|
|
|
|
}},
|
|
|
|
{"codeActionProvider", true},
|
|
|
|
{"completionProvider",
|
|
|
|
json::obj{
|
|
|
|
{"resolveProvider", false},
|
|
|
|
{"triggerCharacters", {".", ">", ":"}},
|
|
|
|
}},
|
|
|
|
{"signatureHelpProvider",
|
|
|
|
json::obj{
|
|
|
|
{"triggerCharacters", {"(", ","}},
|
|
|
|
}},
|
|
|
|
{"definitionProvider", true},
|
2017-11-09 19:30:04 +08:00
|
|
|
{"renameProvider", true},
|
2017-11-07 23:49:35 +08:00
|
|
|
{"executeCommandProvider",
|
|
|
|
json::obj{
|
|
|
|
{"commands", {ExecuteCommandParams::CLANGD_APPLY_FIX_COMMAND}},
|
|
|
|
}},
|
|
|
|
}}}});
|
2017-10-12 21:29:58 +08:00
|
|
|
if (Params.rootUri && !Params.rootUri->file.empty())
|
|
|
|
Server.setRootPath(Params.rootUri->file);
|
|
|
|
else if (Params.rootPath && !Params.rootPath->empty())
|
|
|
|
Server.setRootPath(*Params.rootPath);
|
2017-05-16 22:40:30 +08:00
|
|
|
}
|
|
|
|
|
2017-10-12 21:29:58 +08:00
|
|
|
void ClangdLSPServer::onShutdown(Ctx C, ShutdownParams &Params) {
|
2017-10-25 16:45:41 +08:00
|
|
|
// Do essentially nothing, just say we're ready to exit.
|
|
|
|
ShutdownRequestReceived = true;
|
Adds a json::Expr type to represent intermediate JSON expressions.
Summary:
This form can be created with a nice clang-format-friendly literal syntax,
and gets escaping right. It knows how to call unparse() on our Protocol types.
All the places where we pass around JSON internally now use this type.
Object properties are sorted (stored as std::map) and so serialization is
canonicalized, with optional prettyprinting (triggered by a -pretty flag).
This makes the lit tests much nicer to read and somewhat nicer to debug.
(Unfortunately the completion tests use CHECK-DAG, which only has
line-granularity, so pretty-printing is disabled there. In future we
could make completion ordering deterministic, or switch to unittests).
Compared to the current approach, it has some efficiencies like avoiding copies
of string literals used as object keys, but is probably slower overall.
I think the code/test quality benefits are worth it.
This patch doesn't attempt to do anything about JSON *parsing*.
It takes direction from the proposal in this doc[1], but is limited in scope
and visibility, for now.
I am of half a mind just to use Expr as the target of a parser, and maybe do a
little string deduplication, but not bother with clever memory allocation.
That would be simple, and fast enough for clangd...
[1] https://docs.google.com/document/d/1OEF9IauWwNuSigZzvvbjc1cVS1uGHRyGTXaoy3DjqM4/edit
+cc d0k so he can tell me not to use std::map.
Reviewers: ioeric, malaperle
Subscribers: bkramer, ilya-biryukov, mgorny, klimek
Differential Revision: https://reviews.llvm.org/D39435
llvm-svn: 317486
2017-11-06 23:40:30 +08:00
|
|
|
C.reply(nullptr);
|
2017-10-12 21:29:58 +08:00
|
|
|
}
|
2017-05-16 22:40:30 +08:00
|
|
|
|
2017-10-25 16:45:41 +08:00
|
|
|
void ClangdLSPServer::onExit(Ctx C, ExitParams &Params) { IsDone = true; }
|
|
|
|
|
2017-10-12 21:29:58 +08:00
|
|
|
void ClangdLSPServer::onDocumentDidOpen(Ctx C,
|
|
|
|
DidOpenTextDocumentParams &Params) {
|
2017-07-06 16:44:54 +08:00
|
|
|
if (Params.metadata && !Params.metadata->extraFlags.empty())
|
2017-09-30 18:08:52 +08:00
|
|
|
CDB.setExtraFlagsForFile(Params.textDocument.uri.file,
|
|
|
|
std::move(Params.metadata->extraFlags));
|
|
|
|
Server.addDocument(Params.textDocument.uri.file, Params.textDocument.text);
|
2017-05-16 22:40:30 +08:00
|
|
|
}
|
|
|
|
|
2017-10-12 21:29:58 +08:00
|
|
|
void ClangdLSPServer::onDocumentDidChange(Ctx C,
|
|
|
|
DidChangeTextDocumentParams &Params) {
|
2017-10-26 18:36:20 +08:00
|
|
|
if (Params.contentChanges.size() != 1)
|
2017-11-07 18:21:02 +08:00
|
|
|
return C.replyError(ErrorCode::InvalidParams,
|
|
|
|
"can only apply one change at a time");
|
2017-05-16 22:40:30 +08:00
|
|
|
// We only support full syncing right now.
|
2017-09-30 18:08:52 +08:00
|
|
|
Server.addDocument(Params.textDocument.uri.file,
|
|
|
|
Params.contentChanges[0].text);
|
2017-05-16 22:40:30 +08:00
|
|
|
}
|
|
|
|
|
2017-10-12 21:29:58 +08:00
|
|
|
void ClangdLSPServer::onFileEvent(Ctx C, DidChangeWatchedFilesParams &Params) {
|
2017-10-03 02:00:37 +08:00
|
|
|
Server.onFileEvent(Params);
|
|
|
|
}
|
|
|
|
|
[clangd] Handle clangd.applyFix server-side
Summary:
When the user selects a fix-it (or any code action with commands), it is
possible to let the client forward the selected command to the server.
When the clangd.applyFix command is handled on the server, it can send a
workspace/applyEdit request to the client. This has the advantage that
the client doesn't explicitly have to know how to handle
clangd.applyFix. Therefore, the code to handle clangd.applyFix in the VS
Code extension (and any other Clangd client) is not required anymore.
Reviewers: ilya-biryukov, sammccall, Nebiroth, hokein
Reviewed By: hokein
Subscribers: ioeric, hokein, rwols, puremourning, bkramer, ilya-biryukov
Tags: #clang-tools-extra
Differential Revision: https://reviews.llvm.org/D39276
llvm-svn: 317322
2017-11-03 21:39:15 +08:00
|
|
|
void ClangdLSPServer::onCommand(Ctx C, ExecuteCommandParams &Params) {
|
|
|
|
if (Params.command == ExecuteCommandParams::CLANGD_APPLY_FIX_COMMAND &&
|
|
|
|
Params.workspaceEdit) {
|
|
|
|
// The flow for "apply-fix" :
|
|
|
|
// 1. We publish a diagnostic, including fixits
|
|
|
|
// 2. The user clicks on the diagnostic, the editor asks us for code actions
|
|
|
|
// 3. We send code actions, with the fixit embedded as context
|
|
|
|
// 4. The user selects the fixit, the editor asks us to apply it
|
|
|
|
// 5. We unwrap the changes and send them back to the editor
|
|
|
|
// 6. The editor applies the changes (applyEdit), and sends us a reply (but
|
|
|
|
// we ignore it)
|
|
|
|
|
|
|
|
ApplyWorkspaceEditParams ApplyEdit;
|
|
|
|
ApplyEdit.edit = *Params.workspaceEdit;
|
Adds a json::Expr type to represent intermediate JSON expressions.
Summary:
This form can be created with a nice clang-format-friendly literal syntax,
and gets escaping right. It knows how to call unparse() on our Protocol types.
All the places where we pass around JSON internally now use this type.
Object properties are sorted (stored as std::map) and so serialization is
canonicalized, with optional prettyprinting (triggered by a -pretty flag).
This makes the lit tests much nicer to read and somewhat nicer to debug.
(Unfortunately the completion tests use CHECK-DAG, which only has
line-granularity, so pretty-printing is disabled there. In future we
could make completion ordering deterministic, or switch to unittests).
Compared to the current approach, it has some efficiencies like avoiding copies
of string literals used as object keys, but is probably slower overall.
I think the code/test quality benefits are worth it.
This patch doesn't attempt to do anything about JSON *parsing*.
It takes direction from the proposal in this doc[1], but is limited in scope
and visibility, for now.
I am of half a mind just to use Expr as the target of a parser, and maybe do a
little string deduplication, but not bother with clever memory allocation.
That would be simple, and fast enough for clangd...
[1] https://docs.google.com/document/d/1OEF9IauWwNuSigZzvvbjc1cVS1uGHRyGTXaoy3DjqM4/edit
+cc d0k so he can tell me not to use std::map.
Reviewers: ioeric, malaperle
Subscribers: bkramer, ilya-biryukov, mgorny, klimek
Differential Revision: https://reviews.llvm.org/D39435
llvm-svn: 317486
2017-11-06 23:40:30 +08:00
|
|
|
C.reply("Fix applied.");
|
[clangd] Handle clangd.applyFix server-side
Summary:
When the user selects a fix-it (or any code action with commands), it is
possible to let the client forward the selected command to the server.
When the clangd.applyFix command is handled on the server, it can send a
workspace/applyEdit request to the client. This has the advantage that
the client doesn't explicitly have to know how to handle
clangd.applyFix. Therefore, the code to handle clangd.applyFix in the VS
Code extension (and any other Clangd client) is not required anymore.
Reviewers: ilya-biryukov, sammccall, Nebiroth, hokein
Reviewed By: hokein
Subscribers: ioeric, hokein, rwols, puremourning, bkramer, ilya-biryukov
Tags: #clang-tools-extra
Differential Revision: https://reviews.llvm.org/D39276
llvm-svn: 317322
2017-11-03 21:39:15 +08:00
|
|
|
// We don't need the response so id == 1 is OK.
|
|
|
|
// Ideally, we would wait for the response and if there is no error, we
|
|
|
|
// would reply success/failure to the original RPC.
|
|
|
|
C.call("workspace/applyEdit", ApplyWorkspaceEditParams::unparse(ApplyEdit));
|
|
|
|
} else {
|
|
|
|
// We should not get here because ExecuteCommandParams would not have
|
|
|
|
// parsed in the first place and this handler should not be called. But if
|
|
|
|
// more commands are added, this will be here has a safe guard.
|
|
|
|
C.replyError(
|
2017-11-07 18:21:02 +08:00
|
|
|
ErrorCode::InvalidParams,
|
|
|
|
llvm::formatv("Unsupported command \"{0}\".", Params.command).str());
|
[clangd] Handle clangd.applyFix server-side
Summary:
When the user selects a fix-it (or any code action with commands), it is
possible to let the client forward the selected command to the server.
When the clangd.applyFix command is handled on the server, it can send a
workspace/applyEdit request to the client. This has the advantage that
the client doesn't explicitly have to know how to handle
clangd.applyFix. Therefore, the code to handle clangd.applyFix in the VS
Code extension (and any other Clangd client) is not required anymore.
Reviewers: ilya-biryukov, sammccall, Nebiroth, hokein
Reviewed By: hokein
Subscribers: ioeric, hokein, rwols, puremourning, bkramer, ilya-biryukov
Tags: #clang-tools-extra
Differential Revision: https://reviews.llvm.org/D39276
llvm-svn: 317322
2017-11-03 21:39:15 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-09 19:30:04 +08:00
|
|
|
void ClangdLSPServer::onRename(Ctx C, RenameParams &Params) {
|
|
|
|
auto File = Params.textDocument.uri.file;
|
|
|
|
auto Replacements = Server.rename(File, Params.position, Params.newName);
|
|
|
|
if (!Replacements) {
|
|
|
|
C.replyError(
|
|
|
|
ErrorCode::InternalError,
|
|
|
|
llvm::toString(Replacements.takeError()));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
std::string Code = Server.getDocument(File);
|
|
|
|
std::vector<TextEdit> Edits = replacementsToEdits(Code, *Replacements);
|
|
|
|
WorkspaceEdit WE;
|
|
|
|
WE.changes = {{llvm::yaml::escape(Params.textDocument.uri.uri), Edits}};
|
|
|
|
C.reply(WorkspaceEdit::unparse(WE));
|
|
|
|
}
|
|
|
|
|
2017-10-12 21:29:58 +08:00
|
|
|
void ClangdLSPServer::onDocumentDidClose(Ctx C,
|
|
|
|
DidCloseTextDocumentParams &Params) {
|
2017-09-30 18:08:52 +08:00
|
|
|
Server.removeDocument(Params.textDocument.uri.file);
|
2017-05-16 22:40:30 +08:00
|
|
|
}
|
|
|
|
|
2017-09-30 18:08:52 +08:00
|
|
|
void ClangdLSPServer::onDocumentOnTypeFormatting(
|
2017-10-12 21:29:58 +08:00
|
|
|
Ctx C, DocumentOnTypeFormattingParams &Params) {
|
2017-05-16 22:40:30 +08:00
|
|
|
auto File = Params.textDocument.uri.file;
|
2017-09-30 18:08:52 +08:00
|
|
|
std::string Code = Server.getDocument(File);
|
Adds a json::Expr type to represent intermediate JSON expressions.
Summary:
This form can be created with a nice clang-format-friendly literal syntax,
and gets escaping right. It knows how to call unparse() on our Protocol types.
All the places where we pass around JSON internally now use this type.
Object properties are sorted (stored as std::map) and so serialization is
canonicalized, with optional prettyprinting (triggered by a -pretty flag).
This makes the lit tests much nicer to read and somewhat nicer to debug.
(Unfortunately the completion tests use CHECK-DAG, which only has
line-granularity, so pretty-printing is disabled there. In future we
could make completion ordering deterministic, or switch to unittests).
Compared to the current approach, it has some efficiencies like avoiding copies
of string literals used as object keys, but is probably slower overall.
I think the code/test quality benefits are worth it.
This patch doesn't attempt to do anything about JSON *parsing*.
It takes direction from the proposal in this doc[1], but is limited in scope
and visibility, for now.
I am of half a mind just to use Expr as the target of a parser, and maybe do a
little string deduplication, but not bother with clever memory allocation.
That would be simple, and fast enough for clangd...
[1] https://docs.google.com/document/d/1OEF9IauWwNuSigZzvvbjc1cVS1uGHRyGTXaoy3DjqM4/edit
+cc d0k so he can tell me not to use std::map.
Reviewers: ioeric, malaperle
Subscribers: bkramer, ilya-biryukov, mgorny, klimek
Differential Revision: https://reviews.llvm.org/D39435
llvm-svn: 317486
2017-11-06 23:40:30 +08:00
|
|
|
C.reply(json::ary(
|
|
|
|
replacementsToEdits(Code, Server.formatOnType(File, Params.position))));
|
2017-05-16 22:40:30 +08:00
|
|
|
}
|
|
|
|
|
2017-09-30 18:08:52 +08:00
|
|
|
void ClangdLSPServer::onDocumentRangeFormatting(
|
2017-10-12 21:29:58 +08:00
|
|
|
Ctx C, DocumentRangeFormattingParams &Params) {
|
2017-05-16 22:40:30 +08:00
|
|
|
auto File = Params.textDocument.uri.file;
|
2017-09-30 18:08:52 +08:00
|
|
|
std::string Code = Server.getDocument(File);
|
Adds a json::Expr type to represent intermediate JSON expressions.
Summary:
This form can be created with a nice clang-format-friendly literal syntax,
and gets escaping right. It knows how to call unparse() on our Protocol types.
All the places where we pass around JSON internally now use this type.
Object properties are sorted (stored as std::map) and so serialization is
canonicalized, with optional prettyprinting (triggered by a -pretty flag).
This makes the lit tests much nicer to read and somewhat nicer to debug.
(Unfortunately the completion tests use CHECK-DAG, which only has
line-granularity, so pretty-printing is disabled there. In future we
could make completion ordering deterministic, or switch to unittests).
Compared to the current approach, it has some efficiencies like avoiding copies
of string literals used as object keys, but is probably slower overall.
I think the code/test quality benefits are worth it.
This patch doesn't attempt to do anything about JSON *parsing*.
It takes direction from the proposal in this doc[1], but is limited in scope
and visibility, for now.
I am of half a mind just to use Expr as the target of a parser, and maybe do a
little string deduplication, but not bother with clever memory allocation.
That would be simple, and fast enough for clangd...
[1] https://docs.google.com/document/d/1OEF9IauWwNuSigZzvvbjc1cVS1uGHRyGTXaoy3DjqM4/edit
+cc d0k so he can tell me not to use std::map.
Reviewers: ioeric, malaperle
Subscribers: bkramer, ilya-biryukov, mgorny, klimek
Differential Revision: https://reviews.llvm.org/D39435
llvm-svn: 317486
2017-11-06 23:40:30 +08:00
|
|
|
C.reply(json::ary(
|
|
|
|
replacementsToEdits(Code, Server.formatRange(File, Params.range))));
|
2017-05-16 22:40:30 +08:00
|
|
|
}
|
|
|
|
|
2017-10-12 21:29:58 +08:00
|
|
|
void ClangdLSPServer::onDocumentFormatting(Ctx C,
|
|
|
|
DocumentFormattingParams &Params) {
|
2017-05-16 22:40:30 +08:00
|
|
|
auto File = Params.textDocument.uri.file;
|
2017-09-30 18:08:52 +08:00
|
|
|
std::string Code = Server.getDocument(File);
|
Adds a json::Expr type to represent intermediate JSON expressions.
Summary:
This form can be created with a nice clang-format-friendly literal syntax,
and gets escaping right. It knows how to call unparse() on our Protocol types.
All the places where we pass around JSON internally now use this type.
Object properties are sorted (stored as std::map) and so serialization is
canonicalized, with optional prettyprinting (triggered by a -pretty flag).
This makes the lit tests much nicer to read and somewhat nicer to debug.
(Unfortunately the completion tests use CHECK-DAG, which only has
line-granularity, so pretty-printing is disabled there. In future we
could make completion ordering deterministic, or switch to unittests).
Compared to the current approach, it has some efficiencies like avoiding copies
of string literals used as object keys, but is probably slower overall.
I think the code/test quality benefits are worth it.
This patch doesn't attempt to do anything about JSON *parsing*.
It takes direction from the proposal in this doc[1], but is limited in scope
and visibility, for now.
I am of half a mind just to use Expr as the target of a parser, and maybe do a
little string deduplication, but not bother with clever memory allocation.
That would be simple, and fast enough for clangd...
[1] https://docs.google.com/document/d/1OEF9IauWwNuSigZzvvbjc1cVS1uGHRyGTXaoy3DjqM4/edit
+cc d0k so he can tell me not to use std::map.
Reviewers: ioeric, malaperle
Subscribers: bkramer, ilya-biryukov, mgorny, klimek
Differential Revision: https://reviews.llvm.org/D39435
llvm-svn: 317486
2017-11-06 23:40:30 +08:00
|
|
|
C.reply(json::ary(replacementsToEdits(Code, Server.formatFile(File))));
|
2017-05-16 22:40:30 +08:00
|
|
|
}
|
|
|
|
|
2017-10-12 21:29:58 +08:00
|
|
|
void ClangdLSPServer::onCodeAction(Ctx C, CodeActionParams &Params) {
|
2017-05-16 22:40:30 +08:00
|
|
|
// We provide a code action for each diagnostic at the requested location
|
|
|
|
// which has FixIts available.
|
2017-09-30 18:08:52 +08:00
|
|
|
std::string Code = Server.getDocument(Params.textDocument.uri.file);
|
Adds a json::Expr type to represent intermediate JSON expressions.
Summary:
This form can be created with a nice clang-format-friendly literal syntax,
and gets escaping right. It knows how to call unparse() on our Protocol types.
All the places where we pass around JSON internally now use this type.
Object properties are sorted (stored as std::map) and so serialization is
canonicalized, with optional prettyprinting (triggered by a -pretty flag).
This makes the lit tests much nicer to read and somewhat nicer to debug.
(Unfortunately the completion tests use CHECK-DAG, which only has
line-granularity, so pretty-printing is disabled there. In future we
could make completion ordering deterministic, or switch to unittests).
Compared to the current approach, it has some efficiencies like avoiding copies
of string literals used as object keys, but is probably slower overall.
I think the code/test quality benefits are worth it.
This patch doesn't attempt to do anything about JSON *parsing*.
It takes direction from the proposal in this doc[1], but is limited in scope
and visibility, for now.
I am of half a mind just to use Expr as the target of a parser, and maybe do a
little string deduplication, but not bother with clever memory allocation.
That would be simple, and fast enough for clangd...
[1] https://docs.google.com/document/d/1OEF9IauWwNuSigZzvvbjc1cVS1uGHRyGTXaoy3DjqM4/edit
+cc d0k so he can tell me not to use std::map.
Reviewers: ioeric, malaperle
Subscribers: bkramer, ilya-biryukov, mgorny, klimek
Differential Revision: https://reviews.llvm.org/D39435
llvm-svn: 317486
2017-11-06 23:40:30 +08:00
|
|
|
json::ary Commands;
|
2017-05-16 22:40:30 +08:00
|
|
|
for (Diagnostic &D : Params.context.diagnostics) {
|
|
|
|
std::vector<clang::tooling::Replacement> Fixes =
|
2017-09-30 18:08:52 +08:00
|
|
|
getFixIts(Params.textDocument.uri.file, D);
|
[clangd] Handle clangd.applyFix server-side
Summary:
When the user selects a fix-it (or any code action with commands), it is
possible to let the client forward the selected command to the server.
When the clangd.applyFix command is handled on the server, it can send a
workspace/applyEdit request to the client. This has the advantage that
the client doesn't explicitly have to know how to handle
clangd.applyFix. Therefore, the code to handle clangd.applyFix in the VS
Code extension (and any other Clangd client) is not required anymore.
Reviewers: ilya-biryukov, sammccall, Nebiroth, hokein
Reviewed By: hokein
Subscribers: ioeric, hokein, rwols, puremourning, bkramer, ilya-biryukov
Tags: #clang-tools-extra
Differential Revision: https://reviews.llvm.org/D39276
llvm-svn: 317322
2017-11-03 21:39:15 +08:00
|
|
|
auto Edits = replacementsToEdits(Code, Fixes);
|
Adds a json::Expr type to represent intermediate JSON expressions.
Summary:
This form can be created with a nice clang-format-friendly literal syntax,
and gets escaping right. It knows how to call unparse() on our Protocol types.
All the places where we pass around JSON internally now use this type.
Object properties are sorted (stored as std::map) and so serialization is
canonicalized, with optional prettyprinting (triggered by a -pretty flag).
This makes the lit tests much nicer to read and somewhat nicer to debug.
(Unfortunately the completion tests use CHECK-DAG, which only has
line-granularity, so pretty-printing is disabled there. In future we
could make completion ordering deterministic, or switch to unittests).
Compared to the current approach, it has some efficiencies like avoiding copies
of string literals used as object keys, but is probably slower overall.
I think the code/test quality benefits are worth it.
This patch doesn't attempt to do anything about JSON *parsing*.
It takes direction from the proposal in this doc[1], but is limited in scope
and visibility, for now.
I am of half a mind just to use Expr as the target of a parser, and maybe do a
little string deduplication, but not bother with clever memory allocation.
That would be simple, and fast enough for clangd...
[1] https://docs.google.com/document/d/1OEF9IauWwNuSigZzvvbjc1cVS1uGHRyGTXaoy3DjqM4/edit
+cc d0k so he can tell me not to use std::map.
Reviewers: ioeric, malaperle
Subscribers: bkramer, ilya-biryukov, mgorny, klimek
Differential Revision: https://reviews.llvm.org/D39435
llvm-svn: 317486
2017-11-06 23:40:30 +08:00
|
|
|
if (!Edits.empty()) {
|
|
|
|
WorkspaceEdit WE;
|
|
|
|
WE.changes = {{Params.textDocument.uri.uri, std::move(Edits)}};
|
|
|
|
Commands.push_back(json::obj{
|
|
|
|
{"title", llvm::formatv("Apply FixIt {0}", D.message)},
|
|
|
|
{"command", ExecuteCommandParams::CLANGD_APPLY_FIX_COMMAND},
|
|
|
|
{"arguments", {WE}},
|
|
|
|
});
|
|
|
|
}
|
2017-05-16 22:40:30 +08:00
|
|
|
}
|
Adds a json::Expr type to represent intermediate JSON expressions.
Summary:
This form can be created with a nice clang-format-friendly literal syntax,
and gets escaping right. It knows how to call unparse() on our Protocol types.
All the places where we pass around JSON internally now use this type.
Object properties are sorted (stored as std::map) and so serialization is
canonicalized, with optional prettyprinting (triggered by a -pretty flag).
This makes the lit tests much nicer to read and somewhat nicer to debug.
(Unfortunately the completion tests use CHECK-DAG, which only has
line-granularity, so pretty-printing is disabled there. In future we
could make completion ordering deterministic, or switch to unittests).
Compared to the current approach, it has some efficiencies like avoiding copies
of string literals used as object keys, but is probably slower overall.
I think the code/test quality benefits are worth it.
This patch doesn't attempt to do anything about JSON *parsing*.
It takes direction from the proposal in this doc[1], but is limited in scope
and visibility, for now.
I am of half a mind just to use Expr as the target of a parser, and maybe do a
little string deduplication, but not bother with clever memory allocation.
That would be simple, and fast enough for clangd...
[1] https://docs.google.com/document/d/1OEF9IauWwNuSigZzvvbjc1cVS1uGHRyGTXaoy3DjqM4/edit
+cc d0k so he can tell me not to use std::map.
Reviewers: ioeric, malaperle
Subscribers: bkramer, ilya-biryukov, mgorny, klimek
Differential Revision: https://reviews.llvm.org/D39435
llvm-svn: 317486
2017-11-06 23:40:30 +08:00
|
|
|
C.reply(std::move(Commands));
|
2017-05-16 22:40:30 +08:00
|
|
|
}
|
|
|
|
|
2017-10-12 21:29:58 +08:00
|
|
|
void ClangdLSPServer::onCompletion(Ctx C, TextDocumentPositionParams &Params) {
|
2017-11-15 17:16:29 +08:00
|
|
|
auto List = Server
|
|
|
|
.codeComplete(
|
|
|
|
Params.textDocument.uri.file,
|
|
|
|
Position{Params.position.line, Params.position.character})
|
|
|
|
.get() // FIXME(ibiryukov): This could be made async if we
|
|
|
|
// had an API that would allow to attach callbacks to
|
|
|
|
// futures returned by ClangdServer.
|
|
|
|
.Value;
|
|
|
|
C.reply(List);
|
2017-05-16 22:40:30 +08:00
|
|
|
}
|
|
|
|
|
2017-10-12 21:29:58 +08:00
|
|
|
void ClangdLSPServer::onSignatureHelp(Ctx C,
|
|
|
|
TextDocumentPositionParams &Params) {
|
2017-10-26 20:28:13 +08:00
|
|
|
auto SignatureHelp = Server.signatureHelp(
|
|
|
|
Params.textDocument.uri.file,
|
|
|
|
Position{Params.position.line, Params.position.character});
|
|
|
|
if (!SignatureHelp)
|
2017-11-07 18:21:02 +08:00
|
|
|
return C.replyError(ErrorCode::InvalidParams,
|
|
|
|
llvm::toString(SignatureHelp.takeError()));
|
Adds a json::Expr type to represent intermediate JSON expressions.
Summary:
This form can be created with a nice clang-format-friendly literal syntax,
and gets escaping right. It knows how to call unparse() on our Protocol types.
All the places where we pass around JSON internally now use this type.
Object properties are sorted (stored as std::map) and so serialization is
canonicalized, with optional prettyprinting (triggered by a -pretty flag).
This makes the lit tests much nicer to read and somewhat nicer to debug.
(Unfortunately the completion tests use CHECK-DAG, which only has
line-granularity, so pretty-printing is disabled there. In future we
could make completion ordering deterministic, or switch to unittests).
Compared to the current approach, it has some efficiencies like avoiding copies
of string literals used as object keys, but is probably slower overall.
I think the code/test quality benefits are worth it.
This patch doesn't attempt to do anything about JSON *parsing*.
It takes direction from the proposal in this doc[1], but is limited in scope
and visibility, for now.
I am of half a mind just to use Expr as the target of a parser, and maybe do a
little string deduplication, but not bother with clever memory allocation.
That would be simple, and fast enough for clangd...
[1] https://docs.google.com/document/d/1OEF9IauWwNuSigZzvvbjc1cVS1uGHRyGTXaoy3DjqM4/edit
+cc d0k so he can tell me not to use std::map.
Reviewers: ioeric, malaperle
Subscribers: bkramer, ilya-biryukov, mgorny, klimek
Differential Revision: https://reviews.llvm.org/D39435
llvm-svn: 317486
2017-11-06 23:40:30 +08:00
|
|
|
C.reply(SignatureHelp->Value);
|
2017-10-06 19:54:17 +08:00
|
|
|
}
|
|
|
|
|
2017-10-12 21:29:58 +08:00
|
|
|
void ClangdLSPServer::onGoToDefinition(Ctx C,
|
|
|
|
TextDocumentPositionParams &Params) {
|
2017-10-26 20:28:13 +08:00
|
|
|
auto Items = Server.findDefinitions(
|
|
|
|
Params.textDocument.uri.file,
|
|
|
|
Position{Params.position.line, Params.position.character});
|
|
|
|
if (!Items)
|
2017-11-07 18:21:02 +08:00
|
|
|
return C.replyError(ErrorCode::InvalidParams,
|
|
|
|
llvm::toString(Items.takeError()));
|
Adds a json::Expr type to represent intermediate JSON expressions.
Summary:
This form can be created with a nice clang-format-friendly literal syntax,
and gets escaping right. It knows how to call unparse() on our Protocol types.
All the places where we pass around JSON internally now use this type.
Object properties are sorted (stored as std::map) and so serialization is
canonicalized, with optional prettyprinting (triggered by a -pretty flag).
This makes the lit tests much nicer to read and somewhat nicer to debug.
(Unfortunately the completion tests use CHECK-DAG, which only has
line-granularity, so pretty-printing is disabled there. In future we
could make completion ordering deterministic, or switch to unittests).
Compared to the current approach, it has some efficiencies like avoiding copies
of string literals used as object keys, but is probably slower overall.
I think the code/test quality benefits are worth it.
This patch doesn't attempt to do anything about JSON *parsing*.
It takes direction from the proposal in this doc[1], but is limited in scope
and visibility, for now.
I am of half a mind just to use Expr as the target of a parser, and maybe do a
little string deduplication, but not bother with clever memory allocation.
That would be simple, and fast enough for clangd...
[1] https://docs.google.com/document/d/1OEF9IauWwNuSigZzvvbjc1cVS1uGHRyGTXaoy3DjqM4/edit
+cc d0k so he can tell me not to use std::map.
Reviewers: ioeric, malaperle
Subscribers: bkramer, ilya-biryukov, mgorny, klimek
Differential Revision: https://reviews.llvm.org/D39435
llvm-svn: 317486
2017-11-06 23:40:30 +08:00
|
|
|
C.reply(json::ary(Items->Value));
|
2017-06-29 00:12:10 +08:00
|
|
|
}
|
|
|
|
|
2017-10-12 21:29:58 +08:00
|
|
|
void ClangdLSPServer::onSwitchSourceHeader(Ctx C,
|
|
|
|
TextDocumentIdentifier &Params) {
|
2017-09-30 18:08:52 +08:00
|
|
|
llvm::Optional<Path> Result = Server.switchSourceHeader(Params.uri.file);
|
2017-09-28 11:14:40 +08:00
|
|
|
std::string ResultUri;
|
Adds a json::Expr type to represent intermediate JSON expressions.
Summary:
This form can be created with a nice clang-format-friendly literal syntax,
and gets escaping right. It knows how to call unparse() on our Protocol types.
All the places where we pass around JSON internally now use this type.
Object properties are sorted (stored as std::map) and so serialization is
canonicalized, with optional prettyprinting (triggered by a -pretty flag).
This makes the lit tests much nicer to read and somewhat nicer to debug.
(Unfortunately the completion tests use CHECK-DAG, which only has
line-granularity, so pretty-printing is disabled there. In future we
could make completion ordering deterministic, or switch to unittests).
Compared to the current approach, it has some efficiencies like avoiding copies
of string literals used as object keys, but is probably slower overall.
I think the code/test quality benefits are worth it.
This patch doesn't attempt to do anything about JSON *parsing*.
It takes direction from the proposal in this doc[1], but is limited in scope
and visibility, for now.
I am of half a mind just to use Expr as the target of a parser, and maybe do a
little string deduplication, but not bother with clever memory allocation.
That would be simple, and fast enough for clangd...
[1] https://docs.google.com/document/d/1OEF9IauWwNuSigZzvvbjc1cVS1uGHRyGTXaoy3DjqM4/edit
+cc d0k so he can tell me not to use std::map.
Reviewers: ioeric, malaperle
Subscribers: bkramer, ilya-biryukov, mgorny, klimek
Differential Revision: https://reviews.llvm.org/D39435
llvm-svn: 317486
2017-11-06 23:40:30 +08:00
|
|
|
C.reply(Result ? URI::fromFile(*Result).uri : "");
|
2017-09-28 11:14:40 +08:00
|
|
|
}
|
|
|
|
|
2017-08-14 16:45:47 +08:00
|
|
|
ClangdLSPServer::ClangdLSPServer(JSONOutput &Out, unsigned AsyncThreadsCount,
|
2017-09-12 21:57:14 +08:00
|
|
|
bool SnippetCompletions,
|
2017-10-02 23:13:20 +08:00
|
|
|
llvm::Optional<StringRef> ResourceDir,
|
|
|
|
llvm::Optional<Path> CompileCommandsDir)
|
|
|
|
: Out(Out), CDB(/*Logger=*/Out, std::move(CompileCommandsDir)),
|
2017-09-30 18:08:52 +08:00
|
|
|
Server(CDB, /*DiagConsumer=*/*this, FSProvider, AsyncThreadsCount,
|
2017-10-23 22:46:48 +08:00
|
|
|
clangd::CodeCompleteOptions(
|
|
|
|
/*EnableSnippetsAndCodePatterns=*/SnippetCompletions),
|
|
|
|
/*Logger=*/Out, ResourceDir) {}
|
2017-05-16 17:38:59 +08:00
|
|
|
|
2017-10-25 16:45:41 +08:00
|
|
|
bool ClangdLSPServer::run(std::istream &In) {
|
2017-05-16 22:40:30 +08:00
|
|
|
assert(!IsDone && "Run was called before");
|
2017-05-16 17:38:59 +08:00
|
|
|
|
2017-05-16 22:40:30 +08:00
|
|
|
// Set up JSONRPCDispatcher.
|
2017-10-12 21:29:58 +08:00
|
|
|
JSONRPCDispatcher Dispatcher(
|
|
|
|
[](RequestContext Ctx, llvm::yaml::MappingNode *Params) {
|
2017-11-07 18:21:02 +08:00
|
|
|
Ctx.replyError(ErrorCode::MethodNotFound, "method not found");
|
2017-10-12 21:29:58 +08:00
|
|
|
});
|
2017-09-30 18:08:52 +08:00
|
|
|
registerCallbackHandlers(Dispatcher, Out, /*Callbacks=*/*this);
|
2017-05-16 22:40:30 +08:00
|
|
|
|
|
|
|
// Run the Language Server loop.
|
|
|
|
runLanguageServerLoop(In, Out, Dispatcher, IsDone);
|
2017-05-16 17:38:59 +08:00
|
|
|
|
2017-05-16 22:40:30 +08:00
|
|
|
// Make sure IsDone is set to true after this method exits to ensure assertion
|
|
|
|
// at the start of the method fires if it's ever executed again.
|
|
|
|
IsDone = true;
|
2017-10-25 16:45:41 +08:00
|
|
|
|
|
|
|
return ShutdownRequestReceived;
|
2017-05-16 17:38:59 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<clang::tooling::Replacement>
|
|
|
|
ClangdLSPServer::getFixIts(StringRef File, const clangd::Diagnostic &D) {
|
|
|
|
std::lock_guard<std::mutex> Lock(FixItsMutex);
|
|
|
|
auto DiagToFixItsIter = FixItsMap.find(File);
|
|
|
|
if (DiagToFixItsIter == FixItsMap.end())
|
|
|
|
return {};
|
|
|
|
|
|
|
|
const auto &DiagToFixItsMap = DiagToFixItsIter->second;
|
|
|
|
auto FixItsIter = DiagToFixItsMap.find(D);
|
|
|
|
if (FixItsIter == DiagToFixItsMap.end())
|
|
|
|
return {};
|
|
|
|
|
|
|
|
return FixItsIter->second;
|
|
|
|
}
|
|
|
|
|
2017-09-30 18:08:52 +08:00
|
|
|
void ClangdLSPServer::onDiagnosticsReady(
|
|
|
|
PathRef File, Tagged<std::vector<DiagWithFixIts>> Diagnostics) {
|
Adds a json::Expr type to represent intermediate JSON expressions.
Summary:
This form can be created with a nice clang-format-friendly literal syntax,
and gets escaping right. It knows how to call unparse() on our Protocol types.
All the places where we pass around JSON internally now use this type.
Object properties are sorted (stored as std::map) and so serialization is
canonicalized, with optional prettyprinting (triggered by a -pretty flag).
This makes the lit tests much nicer to read and somewhat nicer to debug.
(Unfortunately the completion tests use CHECK-DAG, which only has
line-granularity, so pretty-printing is disabled there. In future we
could make completion ordering deterministic, or switch to unittests).
Compared to the current approach, it has some efficiencies like avoiding copies
of string literals used as object keys, but is probably slower overall.
I think the code/test quality benefits are worth it.
This patch doesn't attempt to do anything about JSON *parsing*.
It takes direction from the proposal in this doc[1], but is limited in scope
and visibility, for now.
I am of half a mind just to use Expr as the target of a parser, and maybe do a
little string deduplication, but not bother with clever memory allocation.
That would be simple, and fast enough for clangd...
[1] https://docs.google.com/document/d/1OEF9IauWwNuSigZzvvbjc1cVS1uGHRyGTXaoy3DjqM4/edit
+cc d0k so he can tell me not to use std::map.
Reviewers: ioeric, malaperle
Subscribers: bkramer, ilya-biryukov, mgorny, klimek
Differential Revision: https://reviews.llvm.org/D39435
llvm-svn: 317486
2017-11-06 23:40:30 +08:00
|
|
|
json::ary DiagnosticsJSON;
|
2017-05-16 17:38:59 +08:00
|
|
|
|
|
|
|
DiagnosticToReplacementMap LocalFixIts; // Temporary storage
|
2017-09-30 18:08:52 +08:00
|
|
|
for (auto &DiagWithFixes : Diagnostics.Value) {
|
2017-05-16 17:38:59 +08:00
|
|
|
auto Diag = DiagWithFixes.Diag;
|
Adds a json::Expr type to represent intermediate JSON expressions.
Summary:
This form can be created with a nice clang-format-friendly literal syntax,
and gets escaping right. It knows how to call unparse() on our Protocol types.
All the places where we pass around JSON internally now use this type.
Object properties are sorted (stored as std::map) and so serialization is
canonicalized, with optional prettyprinting (triggered by a -pretty flag).
This makes the lit tests much nicer to read and somewhat nicer to debug.
(Unfortunately the completion tests use CHECK-DAG, which only has
line-granularity, so pretty-printing is disabled there. In future we
could make completion ordering deterministic, or switch to unittests).
Compared to the current approach, it has some efficiencies like avoiding copies
of string literals used as object keys, but is probably slower overall.
I think the code/test quality benefits are worth it.
This patch doesn't attempt to do anything about JSON *parsing*.
It takes direction from the proposal in this doc[1], but is limited in scope
and visibility, for now.
I am of half a mind just to use Expr as the target of a parser, and maybe do a
little string deduplication, but not bother with clever memory allocation.
That would be simple, and fast enough for clangd...
[1] https://docs.google.com/document/d/1OEF9IauWwNuSigZzvvbjc1cVS1uGHRyGTXaoy3DjqM4/edit
+cc d0k so he can tell me not to use std::map.
Reviewers: ioeric, malaperle
Subscribers: bkramer, ilya-biryukov, mgorny, klimek
Differential Revision: https://reviews.llvm.org/D39435
llvm-svn: 317486
2017-11-06 23:40:30 +08:00
|
|
|
DiagnosticsJSON.push_back(json::obj{
|
|
|
|
{"range", Diag.range},
|
|
|
|
{"severity", Diag.severity},
|
|
|
|
{"message", Diag.message},
|
|
|
|
});
|
2017-05-16 17:38:59 +08:00
|
|
|
// We convert to Replacements to become independent of the SourceManager.
|
|
|
|
auto &FixItsForDiagnostic = LocalFixIts[Diag];
|
|
|
|
std::copy(DiagWithFixes.FixIts.begin(), DiagWithFixes.FixIts.end(),
|
|
|
|
std::back_inserter(FixItsForDiagnostic));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Cache FixIts
|
|
|
|
{
|
|
|
|
// FIXME(ibiryukov): should be deleted when documents are removed
|
|
|
|
std::lock_guard<std::mutex> Lock(FixItsMutex);
|
|
|
|
FixItsMap[File] = LocalFixIts;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Publish diagnostics.
|
Adds a json::Expr type to represent intermediate JSON expressions.
Summary:
This form can be created with a nice clang-format-friendly literal syntax,
and gets escaping right. It knows how to call unparse() on our Protocol types.
All the places where we pass around JSON internally now use this type.
Object properties are sorted (stored as std::map) and so serialization is
canonicalized, with optional prettyprinting (triggered by a -pretty flag).
This makes the lit tests much nicer to read and somewhat nicer to debug.
(Unfortunately the completion tests use CHECK-DAG, which only has
line-granularity, so pretty-printing is disabled there. In future we
could make completion ordering deterministic, or switch to unittests).
Compared to the current approach, it has some efficiencies like avoiding copies
of string literals used as object keys, but is probably slower overall.
I think the code/test quality benefits are worth it.
This patch doesn't attempt to do anything about JSON *parsing*.
It takes direction from the proposal in this doc[1], but is limited in scope
and visibility, for now.
I am of half a mind just to use Expr as the target of a parser, and maybe do a
little string deduplication, but not bother with clever memory allocation.
That would be simple, and fast enough for clangd...
[1] https://docs.google.com/document/d/1OEF9IauWwNuSigZzvvbjc1cVS1uGHRyGTXaoy3DjqM4/edit
+cc d0k so he can tell me not to use std::map.
Reviewers: ioeric, malaperle
Subscribers: bkramer, ilya-biryukov, mgorny, klimek
Differential Revision: https://reviews.llvm.org/D39435
llvm-svn: 317486
2017-11-06 23:40:30 +08:00
|
|
|
Out.writeMessage(json::obj{
|
|
|
|
{"jsonrpc", "2.0"},
|
|
|
|
{"method", "textDocument/publishDiagnostics"},
|
|
|
|
{"params",
|
|
|
|
json::obj{
|
|
|
|
{"uri", URI::fromFile(File)},
|
|
|
|
{"diagnostics", std::move(DiagnosticsJSON)},
|
|
|
|
}},
|
|
|
|
});
|
2017-05-16 17:38:59 +08:00
|
|
|
}
|