Allow remote loading for DAP-only extensions (#33981)

feeiyu created

Closes #ISSUE


![image](https://github.com/user-attachments/assets/8e1766e4-5d89-4263-875d-ad0dff5c55c2)


Release Notes:

- Allow remote loading for DAP-only extensions

Change summary

crates/debug_adapter_extension/src/extension_locator_adapter.rs |  6 
crates/extension/src/extension_manifest.rs                      |  6 
crates/extension_host/src/extension_host.rs                     |  2 
crates/extension_host/src/headless_host.rs                      | 40 +-
4 files changed, 33 insertions(+), 21 deletions(-)

Detailed changes

crates/debug_adapter_extension/src/extension_locator_adapter.rs 🔗

@@ -44,7 +44,9 @@ impl DapLocator for ExtensionLocatorAdapter {
             .flatten()
     }
 
-    async fn run(&self, _build_config: SpawnInTerminal) -> Result<DebugRequest> {
-        Err(anyhow::anyhow!("Not implemented"))
+    async fn run(&self, build_config: SpawnInTerminal) -> Result<DebugRequest> {
+        self.extension
+            .run_dap_locator(self.locator_name.as_ref().to_owned(), build_config)
+            .await
     }
 }

crates/extension/src/extension_manifest.rs 🔗

@@ -130,6 +130,12 @@ impl ExtensionManifest {
 
         Ok(())
     }
+
+    pub fn allow_remote_load(&self) -> bool {
+        !self.language_servers.is_empty()
+            || !self.debug_adapters.is_empty()
+            || !self.debug_locators.is_empty()
+    }
 }
 
 pub fn build_debug_adapter_schema_path(

crates/extension_host/src/extension_host.rs 🔗

@@ -1670,7 +1670,7 @@ impl ExtensionStore {
                 .extensions
                 .iter()
                 .filter_map(|(id, entry)| {
-                    if entry.manifest.language_servers.is_empty() {
+                    if !entry.manifest.allow_remote_load() {
                         return None;
                     }
                     Some(proto::Extension {

crates/extension_host/src/headless_host.rs 🔗

@@ -125,7 +125,7 @@ impl HeadlessExtensionStore {
 
         let manifest = Arc::new(ExtensionManifest::load(fs.clone(), &extension_dir).await?);
 
-        debug_assert!(!manifest.languages.is_empty() || !manifest.language_servers.is_empty());
+        debug_assert!(!manifest.languages.is_empty() || manifest.allow_remote_load());
 
         if manifest.version.as_ref() != extension.version.as_str() {
             anyhow::bail!(
@@ -165,7 +165,7 @@ impl HeadlessExtensionStore {
             })?;
         }
 
-        if manifest.language_servers.is_empty() {
+        if !manifest.allow_remote_load() {
             return Ok(());
         }
 
@@ -187,24 +187,28 @@ impl HeadlessExtensionStore {
                     );
                 })?;
             }
-            for (debug_adapter, meta) in &manifest.debug_adapters {
-                let schema_path = extension::build_debug_adapter_schema_path(debug_adapter, meta);
+            log::info!("Loaded language server: {}", language_server_id);
+        }
 
-                this.update(cx, |this, _cx| {
-                    this.proxy.register_debug_adapter(
-                        wasm_extension.clone(),
-                        debug_adapter.clone(),
-                        &extension_dir.join(schema_path),
-                    );
-                })?;
-            }
+        for (debug_adapter, meta) in &manifest.debug_adapters {
+            let schema_path = extension::build_debug_adapter_schema_path(debug_adapter, meta);
 
-            for debug_adapter in manifest.debug_locators.keys() {
-                this.update(cx, |this, _cx| {
-                    this.proxy
-                        .register_debug_locator(wasm_extension.clone(), debug_adapter.clone());
-                })?;
-            }
+            this.update(cx, |this, _cx| {
+                this.proxy.register_debug_adapter(
+                    wasm_extension.clone(),
+                    debug_adapter.clone(),
+                    &extension_dir.join(schema_path),
+                );
+            })?;
+            log::info!("Loaded debug adapter: {}", debug_adapter);
+        }
+
+        for debug_locator in manifest.debug_locators.keys() {
+            this.update(cx, |this, _cx| {
+                this.proxy
+                    .register_debug_locator(wasm_extension.clone(), debug_locator.clone());
+            })?;
+            log::info!("Loaded debug locator: {}", debug_locator);
         }
 
         Ok(())