mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
LSP for solcjs
This commit is contained in:
committed by
Christian Parpart
parent
c6ac1625bd
commit
e1947faa1a
@@ -7,6 +7,9 @@ if (EMSCRIPTEN)
|
||||
solidity_alloc
|
||||
solidity_free
|
||||
solidity_reset
|
||||
solidity_lsp_start
|
||||
solidity_lsp_send
|
||||
solidity_lsp_send_receive
|
||||
)
|
||||
# Specify which functions to export in soljson.js.
|
||||
# Note that additional Emscripten-generated methods needed by solc-js are
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#include <libsolc/libsolc.h>
|
||||
#include <libsolidity/interface/StandardCompiler.h>
|
||||
#include <libsolidity/interface/Version.h>
|
||||
#include <libsolidity/lsp/LanguageServer.h>
|
||||
#include <libsolidity/lsp/Transport.h>
|
||||
#include <libyul/YulString.h>
|
||||
|
||||
#include <cstdlib>
|
||||
@@ -112,6 +114,9 @@ string compile(string _input, CStyleReadFileCallback _readCallback, void* _readC
|
||||
return compiler.compile(move(_input));
|
||||
}
|
||||
|
||||
unique_ptr<lsp::MockTransport> languageServerTransport;
|
||||
unique_ptr<lsp::LanguageServer> languageServer;
|
||||
|
||||
}
|
||||
|
||||
extern "C"
|
||||
@@ -132,6 +137,56 @@ extern char* solidity_compile(char const* _input, CStyleReadFileCallback _readCa
|
||||
return solidityAllocations.emplace_back(compile(_input, _readCallback, _readContext)).data();
|
||||
}
|
||||
|
||||
extern int solidity_lsp_start(CStyleReadFileCallback /*TODO(pr) _readCallback*/, void* /*_readContext*/) noexcept
|
||||
{
|
||||
if (languageServer || languageServerTransport)
|
||||
return -1;
|
||||
|
||||
languageServerTransport = make_unique<lsp::MockTransport>();
|
||||
languageServer = make_unique<lsp::LanguageServer>(*languageServerTransport);
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern int solidity_lsp_send(char const* _input) noexcept
|
||||
{
|
||||
if (!languageServer)
|
||||
return -1;
|
||||
|
||||
if (languageServer->isRunning())
|
||||
return -2;
|
||||
|
||||
solAssert(languageServerTransport, "");
|
||||
|
||||
std::string errors{};
|
||||
Json::Value jsonMessage{};
|
||||
if (!jsonParseStrict(_input, jsonMessage, &errors))
|
||||
return -3;
|
||||
|
||||
languageServerTransport->appendInput(jsonMessage);
|
||||
languageServer->runIteration();
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern char const* solidity_try_receive() noexcept
|
||||
{
|
||||
if (!languageServerTransport)
|
||||
return "";
|
||||
|
||||
optional<Json::Value> messageJson = languageServerTransport->popOutput();
|
||||
if (!messageJson)
|
||||
return "";
|
||||
|
||||
return solidityAllocations.emplace_back(jsonPrettyPrint(messageJson.value())).data();
|
||||
}
|
||||
|
||||
extern char const* solidity_lsp_send_receive(char const* _input) noexcept
|
||||
{
|
||||
if (solidity_lsp_send(_input) < 0)
|
||||
return "";
|
||||
|
||||
return solidity_try_receive();
|
||||
}
|
||||
|
||||
extern char* solidity_alloc(size_t _size) noexcept
|
||||
{
|
||||
try
|
||||
@@ -156,5 +211,7 @@ extern void solidity_reset() noexcept
|
||||
// can be freed here.
|
||||
yul::YulStringRepository::reset();
|
||||
solidityAllocations.clear();
|
||||
languageServer.reset();
|
||||
languageServerTransport.reset();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,6 +90,40 @@ void solidity_free(char* _data) SOLC_NOEXCEPT;
|
||||
/// @returns A pointer to the result. The pointer returned must be freed by the caller using solidity_free() or solidity_reset().
|
||||
char* solidity_compile(char const* _input, CStyleReadFileCallback _readCallback, void* _readContext) SOLC_NOEXCEPT;
|
||||
|
||||
/// @TODO the biggest problem here is that the callback has to be synchronous.
|
||||
/// With "compile" we would just record requested files and trigger a recompile later,
|
||||
/// so we might need a way to trigger a recompile.
|
||||
|
||||
/// Switch into LSP mode. Can be undone using solidity_reset().
|
||||
///
|
||||
/// @returns 0 on success and -1 on failure. A failure can only happen due to mis-use of the API,
|
||||
/// such as, the LSP mode has been already initiated.
|
||||
int solidity_lsp_start(CStyleReadFileCallback _readCallback, void* _readContext) SOLC_NOEXCEPT;
|
||||
|
||||
/// Sends a single JSON-RPC message to the LSP server.
|
||||
/// This message must not include any HTTP headers but only hold the payload.
|
||||
///
|
||||
/// @retval 0 Success.
|
||||
/// @retval -1 Server not initialized.
|
||||
/// @retval -2 Server not running (e.g. termination initiated).
|
||||
/// @retval -3 Could not parse JSON RPC message.
|
||||
int solidity_lsp_send(char const* _input) SOLC_NOEXCEPT;
|
||||
|
||||
/// Tries to pop a pending message from the LSP server.
|
||||
/// @returns either an empty string if not possible
|
||||
/// (e.g. no message available or server shut down) or a stringified JSON response message.
|
||||
char const* solidity_try_receive() SOLC_NOEXCEPT;
|
||||
|
||||
/// Send one or more JSON-RPC messages to the LSP (including the HTTP headers),
|
||||
/// expecting a response.
|
||||
/// If the input is empty, just checks for a pending response.
|
||||
/// @returns JSON-RPC message (inculding HTTP headers), can be empty (or nullptr).
|
||||
/// If the result is not null, it has to be freed by the caller using solidity_free.
|
||||
///
|
||||
/// This can cause the callback provided in solidity_lsp to be invoked.
|
||||
/// Should only be called after having called solidity_lsp.
|
||||
char const *solidity_lsp_send_receive(char const* _input) SOLC_NOEXCEPT;
|
||||
|
||||
/// Frees up any allocated memory.
|
||||
///
|
||||
/// NOTE: the pointer returned by solidity_compile as well as any other pointer retrieved via solidity_alloc()
|
||||
|
||||
Reference in New Issue
Block a user