@@ -6,6 +6,15 @@ import * as semver from 'semver';
6
6
7
7
const Module = module . constructor as any ;
8
8
9
+ interface ReadCallbackReply {
10
+ error ?: string ;
11
+ contents ?: string
12
+ }
13
+
14
+ interface Callbacks {
15
+ import ( path : string ) : ReadCallbackReply ;
16
+ }
17
+
9
18
function setupMethods ( soljson ) {
10
19
let version ;
11
20
if ( '_solidity_version' in soljson ) {
@@ -45,6 +54,7 @@ function setupMethods (soljson) {
45
54
reset = soljson . cwrap ( 'solidity_reset' , null , [ ] ) ;
46
55
}
47
56
57
+ // Copies the string at @p str to @p ptr.
48
58
const copyToCString = function ( str , ptr ) {
49
59
const length = soljson . lengthBytesUTF8 ( str ) ;
50
60
// This is allocating memory using solc's allocator.
@@ -60,6 +70,58 @@ function setupMethods (soljson) {
60
70
soljson . setValue ( ptr , buffer , '*' ) ;
61
71
} ;
62
72
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
+
63
125
// This is to support multiple versions of Emscripten.
64
126
// Take a single `ptr` and returns a `str`.
65
127
const copyFromCString = soljson . UTF8ToString || soljson . Pointer_stringify ;
@@ -92,23 +154,15 @@ function setupMethods (soljson) {
92
154
} ;
93
155
} ;
94
156
157
+ // solc.lspStart(myCallbackHere);
95
158
let lspStart = null ;
96
159
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 ( ) ;
101
161
}
102
162
103
163
let lspSendReceive = null ;
104
164
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 ( ) ;
112
166
}
113
167
114
168
// This calls compile() with args || cb
0 commit comments