From 9e4af31cb5be719e9b23325b970d7995a6d495be Mon Sep 17 00:00:00 2001 From: Christian Parpart Date: Mon, 21 Feb 2022 14:35:08 +0100 Subject: [PATCH] Initial bits for integrating the LSP API. --- README.md | 45 +++++++++++++++++++++++++++++++++++++++++++++ wrapper.ts | 21 +++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/README.md b/README.md index b1378a57..29c23760 100644 --- a/README.md +++ b/README.md @@ -204,6 +204,51 @@ The low-level API is as follows: For examples how to use them, please refer to the README of the above mentioned solc-js releases. +#### Language Server Mode + +Since version 0.8.11, the solidity compiler natively supports the +language server protocol. With solc-js, you can use it as follows: + +```javascript +var solc = require('solc'); + +// Callback to be invoked when additional files have to be opened during +// source code analysis stage. +// +// This function behaves similar to the compilation file reader callback. +function fileReadCallback(path) +{ + if ('path' === 'file:///project/lib.sol') { + return { + contents: 'library L { function f() internal returns (uint) { return 7; } }'; + }; + } + else + return { error: 'File not found' }; +} + +// Put solcjs into LSP mode. +solc.lspStart(fileReadCallback); + +// Send some LSP JSON-RPC message and optionally receive a reply. +var lspMessage = { + 'rootUri': 'file:///project/', + 'capabilities': { + 'textDocument': { + 'publishDiagnostics': {'relatedInformation': true} + }, + 'workspace': { + 'applyEdit': true, + 'configuration': true, + 'didChangeConfiguration': {'dynamicRegistration': true}, + 'workspaceEdit': {'documentChanges': true}, + 'workspaceFolders': true + } + } +}; +var lspReply = JSON.parse(solc.lspSendReceive(JSON.stringify(lspMessage))); +``` + ### Using with Electron **Note:** diff --git a/wrapper.ts b/wrapper.ts index 36c18d74..51b99d68 100755 --- a/wrapper.ts +++ b/wrapper.ts @@ -92,6 +92,25 @@ function setupMethods (soljson) { }; }; + let lspStart = null; + if ('_solidity_lsp_start' in soljson) { + let wrappedLspStart = soljson.cwrap('solidity_lsp_start', 'int', []); + lspStart = function (callbacks) { + return runWithCallbacks(callbacks, wrappedLspStart, []); + }; + } + + let lspSendReceive = null; + if ('_solidity_lsp_send_receive' in soljson) { + let wrappedLspSendReceive = soljson.cwrap('solidity_lsp_send_receive', 'string', ['string']); + lspSendReceive = function (input: String, callbacks) { + // We are reusing the `runWithCallbacks` function that was supposed to + // only receive _solidity_compile as second parameter. + // I may be wrong, but that should work analogous. + return runWithCallbacks(callbacks, wrappedLspSendReceive, [input]); + }; + } + // This calls compile() with args || cb const runWithCallbacks = function (callbacks, compile, args) { if (callbacks) { @@ -324,6 +343,8 @@ function setupMethods (soljson) { importCallback: compileJSONCallback !== null || compileStandard !== null, nativeStandardJSON: compileStandard !== null }, + lspStart: lspStart, + lspSendReceive: lspSendReceive, compile: compileStandardWrapper, // Loads the compiler of the given version from the github repository // instead of from the local filesystem.