Skip to content

Commit d7e7b0b

Browse files
committed
fix(core): route react language ids to js ts servers
1 parent 47fb23e commit d7e7b0b

1 file changed

Lines changed: 64 additions & 4 deletions

File tree

crates/mcpls-core/src/bridge/translator.rs

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -531,10 +531,25 @@ impl Translator {
531531
/// Get a cloned LSP client for a file path based on language detection.
532532
fn get_client_for_file(&self, path: &Path) -> Result<LspClient> {
533533
let language_id = detect_language(path, &self.extension_map);
534-
self.lsp_clients
535-
.get(&language_id)
536-
.cloned()
537-
.ok_or(Error::NoServerForLanguage(language_id))
534+
if let Some(client) = self.lsp_clients.get(&language_id) {
535+
return Ok(client.clone());
536+
}
537+
538+
if let Some(server_language_id) = Self::server_language_id_for_document(&language_id)
539+
&& let Some(client) = self.lsp_clients.get(server_language_id)
540+
{
541+
return Ok(client.clone());
542+
}
543+
544+
Err(Error::NoServerForLanguage(language_id))
545+
}
546+
547+
fn server_language_id_for_document(language_id: &str) -> Option<&'static str> {
548+
match language_id {
549+
"javascriptreact" => Some("javascript"),
550+
"typescriptreact" => Some("typescript"),
551+
_ => None,
552+
}
538553
}
539554

540555
/// Parse and validate a file URI, returning the validated path.
@@ -3209,6 +3224,51 @@ mod tests {
32093224
}
32103225
}
32113226

3227+
#[test]
3228+
fn test_get_client_for_file_routes_tsx_to_typescript_server() {
3229+
let temp_dir = TempDir::new().unwrap();
3230+
let test_file = temp_dir.path().join("component.tsx");
3231+
fs::write(&test_file, "export const Component = () => <div />").unwrap();
3232+
3233+
let mut extension_map = HashMap::new();
3234+
extension_map.insert("tsx".to_string(), "typescriptreact".to_string());
3235+
3236+
let mut translator = Translator::new().with_extensions(extension_map);
3237+
translator.register_client(
3238+
"typescript".to_string(),
3239+
LspClient::new(crate::config::LspServerConfig::typescript()),
3240+
);
3241+
3242+
let client = translator.get_client_for_file(&test_file).unwrap();
3243+
assert_eq!(client.language_id(), "typescript");
3244+
}
3245+
3246+
#[test]
3247+
fn test_get_client_for_file_routes_jsx_to_javascript_server() {
3248+
let temp_dir = TempDir::new().unwrap();
3249+
let test_file = temp_dir.path().join("component.jsx");
3250+
fs::write(&test_file, "export const Component = () => <div />").unwrap();
3251+
3252+
let mut extension_map = HashMap::new();
3253+
extension_map.insert("jsx".to_string(), "javascriptreact".to_string());
3254+
3255+
let javascript_config = crate::config::LspServerConfig {
3256+
language_id: "javascript".to_string(),
3257+
command: "typescript-language-server".to_string(),
3258+
args: vec!["--stdio".to_string()],
3259+
env: HashMap::new(),
3260+
file_patterns: vec!["**/*.js".to_string(), "**/*.jsx".to_string()],
3261+
initialization_options: None,
3262+
timeout_seconds: 30,
3263+
heuristics: None,
3264+
};
3265+
let mut translator = Translator::new().with_extensions(extension_map);
3266+
translator.register_client("javascript".to_string(), LspClient::new(javascript_config));
3267+
3268+
let client = translator.get_client_for_file(&test_file).unwrap();
3269+
assert_eq!(client.language_id(), "javascript");
3270+
}
3271+
32123272
#[tokio::test]
32133273
async fn test_serve_initializes_translator_with_extensions() {
32143274
use crate::config::{LanguageExtensionMapping, WorkspaceConfig};

0 commit comments

Comments
 (0)