Skip to content

Commit 6691f0a

Browse files
authored
Remove extra fields from message (#1115)
1 parent 7c3ddbe commit 6691f0a

File tree

4 files changed

+49
-2
lines changed

4 files changed

+49
-2
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,4 @@ shellexpand = "2.0.0"
3939
derivative = "2.1.1"
4040
anyhow = "1.0.32"
4141
thiserror = "1.0.20"
42+
lazy_static = "1.4.0"

src/main.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ use types::State;
1919

2020
#[macro_use]
2121
extern crate clap;
22+
#[macro_use]
23+
extern crate lazy_static;
2224

2325
fn main() -> Result<()> {
2426
let _ = clap::app_from_crate!().get_matches();

src/rpcclient.rs

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::types::{Call, Id, LSError, LanguageId, RawMessage, ToInt, ToParams, T
22
use anyhow::{anyhow, Result};
33
use crossbeam::channel::{bounded, unbounded, Receiver, Sender};
44
use log::*;
5+
use regex::Regex;
56
use serde::{de::DeserializeOwned, Serialize};
67
use std::io::Write;
78
use std::str::FromStr;
@@ -15,6 +16,13 @@ use std::{
1516

1617
const CONTENT_MODIFIED_ERROR_CODE: i64 = -32801;
1718

19+
lazy_static! {
20+
// this regex is used to remove some additional fields that we get from some servers, namely:
21+
// meta, sent by javascript-typescript-langserver and requestMethod, sent by Sorbet.
22+
static ref RE_REMOVE_EXTRA_FIELDS: Regex =
23+
Regex::new(r#",\s?"(?:meta|requestMethod)":(?:"\w+(/\w+)?"|\{\})"#).unwrap();
24+
}
25+
1826
#[derive(Serialize)]
1927
pub struct RpcClient {
2028
language_id: LanguageId,
@@ -181,8 +189,9 @@ fn loop_read(
181189
continue;
182190
}
183191
info!("<= {:?} {}", language_id, message);
184-
// FIXME: Remove extra `meta` property from javascript-typescript-langserver.
185-
let s = message.replace(r#","meta":{}"#, "");
192+
// FIXME: Remove extra `meta` property from javascript-typescript-langserver and
193+
// `requestMethod` sent by Sorbet.
194+
let s = RE_REMOVE_EXTRA_FIELDS.replace(message, "");
186195
let message = serde_json::from_str(&s);
187196
if let Err(ref err) = message {
188197
error!(
@@ -240,3 +249,37 @@ fn loop_write(
240249
}
241250
Ok(())
242251
}
252+
253+
#[cfg(test)]
254+
mod test {
255+
use super::RE_REMOVE_EXTRA_FIELDS;
256+
use crate::types::RawMessage;
257+
258+
#[test]
259+
// The library we're using for json-rpc doesn't accept extra fields in the structs used to
260+
// deserialize the message. Sorbet (and possibly other servers) sends an extra field in it, so
261+
// the client fails to deserialize that response.
262+
// Our previous solution was to pin the dependency to jsonrpc-core to version 12, but is
263+
// suboptimal, so we now try to remove the extra fields we know of from the response.
264+
//
265+
// See related issue: https://github.com/autozimu/LanguageClient-neovim/issues/892
266+
fn it_should_remove_extra_fields() {
267+
// it removes the requestMethod field from Sorbet
268+
let message = r#"{"jsonrpc":"2.0","id":1,"requestMethod":"initialize","result":0}"#;
269+
let message = RE_REMOVE_EXTRA_FIELDS.replace(message, "");
270+
let result: Result<RawMessage, _> = serde_json::from_str(&message);
271+
assert!(result.is_ok());
272+
273+
let message =
274+
r#"{"jsonrpc":"2.0","id":1,"requestMethod":"textDocument/definition","result":0}"#;
275+
let message = RE_REMOVE_EXTRA_FIELDS.replace(message, "");
276+
let result: Result<RawMessage, _> = serde_json::from_str(&message);
277+
assert!(result.is_ok());
278+
279+
// it removes the meta field from javascript-typescript-langserver
280+
let message = r#"{"jsonrpc":"2.0","id":1,"meta":{},"result":0}"#;
281+
let message = RE_REMOVE_EXTRA_FIELDS.replace(message, "");
282+
let result: Result<RawMessage, _> = serde_json::from_str(&message);
283+
assert!(result.is_ok());
284+
}
285+
}

0 commit comments

Comments
 (0)