diff --git a/crates/extension/src/extension_builder.rs b/crates/extension/src/extension_builder.rs index 7a3897eea7..621ba9250c 100644 --- a/crates/extension/src/extension_builder.rs +++ b/crates/extension/src/extension_builder.rs @@ -1,5 +1,6 @@ use crate::{ - ExtensionLibraryKind, ExtensionManifest, GrammarManifestEntry, parse_wasm_extension_version, + ExtensionLibraryKind, ExtensionManifest, GrammarManifestEntry, build_debug_adapter_schema_path, + parse_wasm_extension_version, }; use anyhow::{Context as _, Result, bail}; use async_compression::futures::bufread::GzipDecoder; @@ -99,12 +100,8 @@ impl ExtensionBuilder { } for (debug_adapter_name, meta) in &mut extension_manifest.debug_adapters { - let debug_adapter_relative_schema_path = - meta.schema_path.clone().unwrap_or_else(|| { - Path::new("debug_adapter_schemas") - .join(Path::new(debug_adapter_name.as_ref()).with_extension("json")) - }); - let debug_adapter_schema_path = extension_dir.join(debug_adapter_relative_schema_path); + let debug_adapter_schema_path = + extension_dir.join(build_debug_adapter_schema_path(debug_adapter_name, meta)); let debug_adapter_schema = fs::read_to_string(&debug_adapter_schema_path) .with_context(|| { diff --git a/crates/extension/src/extension_manifest.rs b/crates/extension/src/extension_manifest.rs index 9439f0c290..4e3f8a3dc2 100644 --- a/crates/extension/src/extension_manifest.rs +++ b/crates/extension/src/extension_manifest.rs @@ -132,6 +132,16 @@ impl ExtensionManifest { } } +pub fn build_debug_adapter_schema_path( + adapter_name: &Arc, + meta: &DebugAdapterManifestEntry, +) -> PathBuf { + meta.schema_path.clone().unwrap_or_else(|| { + Path::new("debug_adapter_schemas") + .join(Path::new(adapter_name.as_ref()).with_extension("json")) + }) +} + /// A capability for an extension. #[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] #[serde(tag = "kind")] @@ -320,6 +330,29 @@ mod tests { } } + #[test] + fn test_build_adapter_schema_path_with_schema_path() { + let adapter_name = Arc::from("my_adapter"); + let entry = DebugAdapterManifestEntry { + schema_path: Some(PathBuf::from("foo/bar")), + }; + + let path = build_debug_adapter_schema_path(&adapter_name, &entry); + assert_eq!(path, PathBuf::from("foo/bar")); + } + + #[test] + fn test_build_adapter_schema_path_without_schema_path() { + let adapter_name = Arc::from("my_adapter"); + let entry = DebugAdapterManifestEntry { schema_path: None }; + + let path = build_debug_adapter_schema_path(&adapter_name, &entry); + assert_eq!( + path, + PathBuf::from("debug_adapter_schemas").join("my_adapter.json") + ); + } + #[test] fn test_allow_exact_match() { let manifest = ExtensionManifest { diff --git a/crates/extension_host/src/extension_host.rs b/crates/extension_host/src/extension_host.rs index 8d3a218a03..eb6fb52eb8 100644 --- a/crates/extension_host/src/extension_host.rs +++ b/crates/extension_host/src/extension_host.rs @@ -1639,6 +1639,23 @@ impl ExtensionStore { } } + for (adapter_name, meta) in loaded_extension.manifest.debug_adapters.iter() { + let schema_path = &extension::build_debug_adapter_schema_path(adapter_name, meta); + + if fs.is_file(&src_dir.join(schema_path)).await { + match schema_path.parent() { + Some(parent) => fs.create_dir(&tmp_dir.join(parent)).await?, + None => {} + } + fs.copy_file( + &src_dir.join(schema_path), + &tmp_dir.join(schema_path), + fs::CopyOptions::default(), + ) + .await? + } + } + Ok(()) }) } diff --git a/crates/extension_host/src/headless_host.rs b/crates/extension_host/src/headless_host.rs index 31626c50d8..ad3931ce83 100644 --- a/crates/extension_host/src/headless_host.rs +++ b/crates/extension_host/src/headless_host.rs @@ -4,8 +4,8 @@ use anyhow::{Context as _, Result}; use client::{TypedEnvelope, proto}; use collections::{HashMap, HashSet}; use extension::{ - Extension, ExtensionHostProxy, ExtensionLanguageProxy, ExtensionLanguageServerProxy, - ExtensionManifest, + Extension, ExtensionDebugAdapterProviderProxy, ExtensionHostProxy, ExtensionLanguageProxy, + ExtensionLanguageServerProxy, ExtensionManifest, }; use fs::{Fs, RemoveOptions, RenameOptions}; use gpui::{App, AppContext as _, AsyncApp, Context, Entity, Task, WeakEntity}; @@ -169,8 +169,9 @@ impl HeadlessExtensionStore { return Ok(()); } - let wasm_extension: Arc = - Arc::new(WasmExtension::load(extension_dir, &manifest, wasm_host.clone(), &cx).await?); + let wasm_extension: Arc = Arc::new( + WasmExtension::load(extension_dir.clone(), &manifest, wasm_host.clone(), &cx).await?, + ); for (language_server_id, language_server_config) in &manifest.language_servers { for language in language_server_config.languages() { @@ -186,6 +187,24 @@ impl HeadlessExtensionStore { ); })?; } + for (debug_adapter, meta) in &manifest.debug_adapters { + let schema_path = extension::build_debug_adapter_schema_path(debug_adapter, meta); + + this.update(cx, |this, _cx| { + this.proxy.register_debug_adapter( + wasm_extension.clone(), + debug_adapter.clone(), + &extension_dir.join(schema_path), + ); + })?; + } + + for debug_adapter in manifest.debug_locators.keys() { + this.update(cx, |this, _cx| { + this.proxy + .register_debug_locator(wasm_extension.clone(), debug_adapter.clone()); + })?; + } } Ok(())