@@ -125,11 +125,6 @@ impl RequestTracker {
125125 raw_bytes : & mut Bytes ,
126126 pair : & Pair ,
127127 ) -> std:: io:: Result < ( ) > {
128- // If the LSP is not in a container, there is no need to track this.
129- if !self . config . use_docker {
130- return Ok ( ( ) ) ;
131- }
132-
133128 match pair {
134129 Pair :: Server => {
135130 if self . map . read ( ) . await . is_empty ( ) {
@@ -141,11 +136,11 @@ impl RequestTracker {
141136 trace ! ( server_response=%v, "received" ) ;
142137
143138 // Check if this is a response to a tracked request
144- if let Some ( id) = v. get ( "id" ) . and_then ( Value :: as_u64) {
145- if let Some ( tracked_method) = self . map . write ( ) . await . remove ( & id) {
146- self . plugins . process ( self , & mut v , & tracked_method ) . await ? ;
147- * raw_bytes = Bytes :: from ( serde_json :: to_vec ( & v ) ? ) ;
148- }
139+ if let Some ( id) = v. get ( "id" ) . and_then ( Value :: as_u64)
140+ && let Some ( tracked_method) = self . map . write ( ) . await . remove ( & id)
141+ {
142+ self . plugins . process ( self , & mut v , & tracked_method ) . await ? ;
143+ * raw_bytes = Bytes :: from ( serde_json :: to_vec ( & v ) ? ) ;
149144 }
150145 }
151146
@@ -258,102 +253,65 @@ pub fn redirect_goto_methods<'a>(
258253 v : & ' a mut Value ,
259254) -> Pin < Box < dyn Future < Output = std:: io:: Result < ( ) > > + Send + ' a > > {
260255 Box :: pin ( async move {
256+ // If the LSP is not in a container, there is no need to track this.
257+ if !tracker. config . use_docker {
258+ return Ok ( ( ) ) ;
259+ }
261260 if let Some ( results) = v. get_mut ( "result" ) . and_then ( Value :: as_array_mut) {
262261 for result in results {
263- if let Some ( uri_val) = result. get ( "uri" ) . and_then ( |u| u. as_str ( ) ) {
264- if !uri_val. contains ( & tracker. config . local_path ) {
265- let new_uri = tracker. bind_library ( uri_val) . await ?;
266- RequestTracker :: modify_uri ( result, & new_uri) ;
267- }
268- }
269- }
270- }
271- Ok ( ( ) )
272- } )
273- }
274-
275- pub fn test_hover < ' a > (
276- _tracker : & ' a RequestTracker ,
277- v : & ' a mut Value ,
278- ) -> Pin < Box < dyn Future < Output = std:: io:: Result < ( ) > > + Send + ' a > > {
279- Box :: pin ( async move {
280- if let Some ( result) = v. get_mut ( "result" ) . filter ( |r| !r. is_null ( ) ) {
281- if let Some ( value) = result. get_mut ( "contents" ) . and_then ( |c| c. get_mut ( "value" ) ) {
282- if let Some ( s) = value. as_str ( ) {
283- * value = Value :: String ( s. replace ( "a" , "e" ) ) ;
262+ if let Some ( uri_val) = result. get ( "uri" ) . and_then ( |u| u. as_str ( ) )
263+ && !uri_val. contains ( & tracker. config . local_path )
264+ {
265+ let new_uri = tracker. bind_library ( uri_val) . await ?;
266+ RequestTracker :: modify_uri ( result, & new_uri) ;
284267 }
285268 }
286269 }
287270 Ok ( ( ) )
288271 } )
289272}
290273
274+ /// Override any root resolver to the docker internal path,
275+ /// this ensure that the LSP can consume it correctly independent
276+ /// of the IDE
291277pub fn ensure_root ( msg : & mut Bytes , config : & ProxyConfig ) {
292278 let docker_uri = format ! ( "file://{}" , config. docker_internal_path) ;
293279
294- for key in [ b"\" rootUri\" :\" " . as_slice ( ) , b"\" rootPath\" :\" " ] {
295- if let Some ( beg) = find ( msg, key) . map ( |p| p + key. len ( ) ) {
296- if let Some ( end) = find ( & msg[ beg..] , b"\" " ) . map ( |p| p + beg) {
297- let before = & msg[ ..beg] ;
298- let after = & msg[ end..] ;
299- * msg = Bytes :: from ( [ before, docker_uri. as_bytes ( ) , after] . concat ( ) ) ;
300- }
301- }
280+ // rootPath is deprecated since 3.0 in favour of rootUri
281+ // but we want to support it anyway, notice that this
282+ // use the path not as a uri (misses the `file://` prefix)
283+ let key = b"\" rootPath\" :\" " . as_slice ( ) ;
284+ if let Some ( beg) = find ( msg, key) . map ( |p| p + key. len ( ) )
285+ && let Some ( end) = find ( & msg[ beg..] , b"\" " ) . map ( |p| p + beg)
286+ {
287+ let before = & msg[ ..beg] ;
288+ let after = & msg[ end..] ;
289+ * msg = Bytes :: from ( [ before, config. docker_internal_path . as_bytes ( ) , after] . concat ( ) ) ;
290+ }
291+
292+ // rootUri is deprecated since 3.6 in favour of workspaceFolders
293+ // but we want to support it anyway
294+ let key = b"\" rootUri\" :\" " . as_slice ( ) ;
295+ if let Some ( beg) = find ( msg, key) . map ( |p| p + key. len ( ) )
296+ && let Some ( end) = find ( & msg[ beg..] , b"\" " ) . map ( |p| p + beg)
297+ {
298+ let before = & msg[ ..beg] ;
299+ let after = & msg[ end..] ;
300+ * msg = Bytes :: from ( [ before, docker_uri. as_bytes ( ) , after] . concat ( ) ) ;
302301 }
303302
303+ // Active root resolver, if it is present, then will override `rootPath` and `rootUri`
304304 let key = b"\" workspaceFolders\" :[" ;
305- if let Some ( beg) = find ( msg, key) . map ( |p| p + key. len ( ) ) {
306- if let Some ( end) = find ( & msg[ beg..] , b"]" ) . map ( |p| p + beg) {
307- if let Some ( ws) = patch_workspace_folders ( & msg[ beg..end] , & docker_uri) {
308- let before = & msg[ ..beg] ;
309- let after = & msg[ end..] ;
310- * msg = Bytes :: from ( [ before, & ws, after] . concat ( ) ) ;
311- }
312- }
305+ if let Some ( beg) = find ( msg, key) . map ( |p| p + key. len ( ) )
306+ && let Some ( end) = find ( & msg[ beg..] , b"]" ) . map ( |p| p + beg)
307+ && let Some ( ws) = patch_workspace_folders ( & msg[ beg..end] , & docker_uri)
308+ {
309+ let before = & msg[ ..beg] ;
310+ let after = & msg[ end..] ;
311+ * msg = Bytes :: from ( [ before, & ws, after] . concat ( ) ) ;
313312 }
314313}
315314
316- // pub fn ensure_root(msg: &mut Bytes, config: &ProxyConfig) {
317- // let docker_uri = format!("file://{}", config.docker_internal_path);
318- //
319- // // Patch rootUri
320- // let key = b"\"rootUri\":\"";
321- // if let Some(mut beg) = find(msg, key) {
322- // beg += key.len();
323- // if let Some(mut end) = find(&msg[beg..], b"\"") {
324- // end += beg; // Make it absolute position
325- // let before = &msg[..beg];
326- // let after = &msg[end..];
327- // *msg = Bytes::from([before, docker_uri.as_bytes(), after].concat());
328- // }
329- // }
330- //
331- // // Patch rootPath if present
332- // let key = b"\"rootPath\":\"";
333- // if let Some(mut beg) = find(msg, key) {
334- // beg += key.len();
335- // if let Some(mut end) = find(&msg[beg..], b"\"") {
336- // end += beg;
337- // let before = &msg[..beg];
338- // let after = &msg[end..];
339- // *msg = Bytes::from([before, docker_uri.as_bytes(), after].concat());
340- // }
341- // }
342- //
343- // let key = b"\"workspaceFolders\":[";
344- // if let Some(mut beg) = find(msg, key) {
345- // beg += key.len();
346- // if let Some(mut end) = find(&msg[beg..], b"]") {
347- // end += beg;
348- // let before = &msg[..beg];
349- // let after = &msg[end..];
350- // if let Some(ws) = patch_workspace_folders(&msg[beg..end], &docker_uri) {
351- // *msg = Bytes::from([before, &ws, after].concat());
352- // }
353- // }
354- // }
355- // }
356-
357315fn patch_workspace_folders ( msg : & [ u8 ] , docker_uri : & str ) -> Option < Bytes > {
358316 let key = b"\" uri\" :\" " ;
359317 let mut result = None ;
@@ -404,8 +362,8 @@ mod tests {
404362
405363 // From Client to Server
406364
407- let rq = lspmsg ! ( "uri" : "/test/path" , "method" : "text/document" , "workspaceFolder " : "/test/path" ) ;
408- let ex = lspmsg ! ( "uri" : "/usr/home/app" , "method" : "text/document" , "workspaceFolder " : "/usr/home/app" ) ;
365+ let rq = lspmsg ! ( "uri" : "/test/path" , "method" : "text/document" , "workspaceFolders " : "[ \" name \" : \" something \" , \" uri \" : \" /test/path\" ] " ) ;
366+ let ex = lspmsg ! ( "uri" : "/usr/home/app" , "method" : "text/document" , "workspaceFolders " : "[ \" name \" : \" something \" , \" uri \" : \" /usr/home/app\" ] " ) ;
409367
410368 let mut request = Bytes :: from ( rq. clone ( ) ) ;
411369 let mut expected = Bytes :: from ( ex) ;
@@ -436,15 +394,23 @@ mod tests {
436394 let msg = lspmsg ! (
437395 "method" : "initialize" ,
438396 "rootUri" : "file:///test/path" ,
439- "rootPath" : "/test/path"
397+ "rootPath" : "/test/path" ,
398+ "workspaceFolders" : "[\" uri\" :\" /test/path\" ,\" name\" :\" something\" ]"
440399 ) ;
441400
442401 let mut request = Bytes :: from ( msg) ;
443402 ensure_root ( & mut request, & config) ;
444403
445404 let body = lspbody ! ( & request => "string" ) ;
446405 assert ! ( find( body, b"\" rootUri\" :\" file:///usr/home/app\" " ) . is_some( ) ) ;
447- assert ! ( find( body, b"\" rootPath\" :\" file:///usr/home/app\" " ) . is_some( ) ) ;
406+ assert ! ( find( body, b"\" rootPath\" :\" /usr/home/app\" " ) . is_some( ) ) ;
407+ assert ! (
408+ find(
409+ body,
410+ b"\" workspaceFolders\" :[\" uri\" :\" file:///usr/home/app\" ,\" name\" :\" something\" ]"
411+ )
412+ . is_some( )
413+ ) ;
448414 }
449415}
450416
0 commit comments