Skip to content

Commit 806856a

Browse files
continued WIP-work on LSP bindings
1 parent 5ca4f0c commit 806856a

File tree

1 file changed

+65
-11
lines changed

1 file changed

+65
-11
lines changed

wrapper.ts

Lines changed: 65 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@ import * as semver from 'semver';
66

77
const Module = module.constructor as any;
88

9+
interface ReadCallbackReply {
10+
error?: string;
11+
contents?: string
12+
}
13+
14+
interface Callbacks {
15+
import(path: string): ReadCallbackReply;
16+
}
17+
918
function setupMethods (soljson) {
1019
let version;
1120
if ('_solidity_version' in soljson) {
@@ -45,6 +54,7 @@ function setupMethods (soljson) {
4554
reset = soljson.cwrap('solidity_reset', null, []);
4655
}
4756

57+
// Copies the string at @p str to @p ptr.
4858
const copyToCString = function (str, ptr) {
4959
const length = soljson.lengthBytesUTF8(str);
5060
// This is allocating memory using solc's allocator.
@@ -60,6 +70,58 @@ function setupMethods (soljson) {
6070
soljson.setValue(ptr, buffer, '*');
6171
};
6272

73+
const createWrappedLspSend = function() {
74+
const wrappedLspSend = soljson.cwrap('solidity_lsp_send', 'number', ['string']);
75+
return function (input: String) {
76+
let args = [];
77+
args.push(JSON.stringify(input));
78+
return wrappedLspSend.apply(undefined, args);
79+
};
80+
};
81+
82+
// Creates a wrapper around `int solidity_lsp_start(callbacks: Callbacks)`.
83+
const createWrappedLspStart = function() {
84+
const wrappedLspStart = soljson.cwrap('solidity_lsp_start', 'number', []);
85+
return function (callbacks: Callbacks) {
86+
let readCallback = callbacks.import;
87+
assert(typeof readCallback === 'function', 'Invalid callback specified.');
88+
const copyFromCString = soljson.UTF8ToString || soljson.Pointer_stringify;
89+
90+
const wrappedReadCallback = function (path: string, contents: string, error: string) {
91+
// Calls the user-supplied file read callback and passes the return values
92+
// accordingly to either @p contents or into @p error on failure.
93+
const result = readCallback(copyFromCString(path));
94+
if (typeof result.contents === 'string') {
95+
copyToCString(result.contents, contents);
96+
}
97+
if (typeof result.error === 'string') {
98+
copyToCString(result.error, error);
99+
}
100+
};
101+
102+
const addFunction = soljson.addFunction || soljson.Runtime.addFunction;
103+
const removeFunction = soljson.removeFunction || soljson.Runtime.removeFunction;
104+
const wrappedFunctionId = addFunction(wrappedReadCallback, 'ii');
105+
106+
try {
107+
// call solidity_lsp_start(callbacks)
108+
let args = [];
109+
args.push(wrappedFunctionId);
110+
let output = wrappedLspStart.apply(undefined, args);
111+
removeFunction(wrappedFunctionId);
112+
return output;
113+
} catch (e) {
114+
removeFunction(wrappedFunctionId);
115+
throw e;
116+
}
117+
// NOTE: We MUST NOT reset the compiler here.
118+
// We instead could try to make sure to only release memory that is
119+
// safe to be released.
120+
// Probably by clearly defining semantics and memory lifetimes
121+
// of output strings.
122+
};
123+
};
124+
63125
// This is to support multiple versions of Emscripten.
64126
// Take a single `ptr` and returns a `str`.
65127
const copyFromCString = soljson.UTF8ToString || soljson.Pointer_stringify;
@@ -92,23 +154,15 @@ function setupMethods (soljson) {
92154
};
93155
};
94156

157+
// solc.lspStart(myCallbackHere);
95158
let lspStart = null;
96159
if ('_solidity_lsp_start' in soljson) {
97-
const wrappedLspStart = soljson.cwrap('solidity_lsp_start', 'int', []);
98-
lspStart = function (callbacks) {
99-
return runWithCallbacks(callbacks, wrappedLspStart, []);
100-
};
160+
lspStart = createWrappedLspStart();
101161
}
102162

103163
let lspSendReceive = null;
104164
if ('_solidity_lsp_send_receive' in soljson) {
105-
const wrappedLspSendReceive = soljson.cwrap('solidity_lsp_send_receive', 'string', ['string']);
106-
lspSendReceive = function (input: String, callbacks) {
107-
// We are reusing the `runWithCallbacks` function that was supposed to
108-
// only receive _solidity_compile as second parameter.
109-
// I may be wrong, but that should work analogous.
110-
return runWithCallbacks(callbacks, wrappedLspSendReceive, [input]);
111-
};
165+
lspSendReceive = createWrappedLspSend();
112166
}
113167

114168
// This calls compile() with args || cb

0 commit comments

Comments
 (0)