mirror of
https://github.com/denoland/deno.git
synced 2025-01-21 21:50:00 -05:00
fix(lsp): updates to workspace config are processed sync (#10812)
This commit is contained in:
parent
e466a6fc9a
commit
9abb899f5f
4 changed files with 203 additions and 57 deletions
|
@ -165,8 +165,8 @@ impl ConfigSnapshot {
|
|||
}
|
||||
|
||||
enum ConfigRequest {
|
||||
All,
|
||||
Specifier(ModuleSpecifier, ModuleSpecifier),
|
||||
Workspace,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone)]
|
||||
|
@ -197,12 +197,8 @@ impl Config {
|
|||
loop {
|
||||
match rx.recv().await {
|
||||
None => break,
|
||||
Some(ConfigRequest::Workspace) => {
|
||||
let mut items = vec![lsp::ConfigurationItem {
|
||||
scope_uri: None,
|
||||
section: Some(SETTINGS_SECTION.to_string()),
|
||||
}];
|
||||
let (specifier_uri_map, mut specifier_items): (
|
||||
Some(ConfigRequest::All) => {
|
||||
let (specifier_uri_map, items): (
|
||||
Vec<(ModuleSpecifier, ModuleSpecifier)>,
|
||||
Vec<lsp::ConfigurationItem>,
|
||||
) = {
|
||||
|
@ -223,40 +219,18 @@ impl Config {
|
|||
.collect(),
|
||||
)
|
||||
};
|
||||
items.append(&mut specifier_items);
|
||||
if let Ok(configs) = client.configuration(items).await {
|
||||
let mut settings = settings_ref.write().unwrap();
|
||||
for (i, value) in configs.into_iter().enumerate() {
|
||||
match i {
|
||||
0 => {
|
||||
match serde_json::from_value::<WorkspaceSettings>(value) {
|
||||
Ok(workspace_settings) => {
|
||||
settings.workspace = workspace_settings;
|
||||
}
|
||||
Err(err) => {
|
||||
error!(
|
||||
"Error converting workspace settings: {}",
|
||||
err
|
||||
);
|
||||
}
|
||||
}
|
||||
match serde_json::from_value::<SpecifierSettings>(value) {
|
||||
Ok(specifier_settings) => {
|
||||
let (specifier, uri) = specifier_uri_map[i].clone();
|
||||
settings
|
||||
.specifiers
|
||||
.insert(specifier, (uri, specifier_settings));
|
||||
}
|
||||
_ => {
|
||||
match serde_json::from_value::<SpecifierSettings>(value) {
|
||||
Ok(specifier_settings) => {
|
||||
let (specifier, uri) =
|
||||
specifier_uri_map[i - 1].clone();
|
||||
settings
|
||||
.specifiers
|
||||
.insert(specifier, (uri, specifier_settings));
|
||||
}
|
||||
Err(err) => {
|
||||
error!(
|
||||
"Error converting specifier settings: {}",
|
||||
err
|
||||
);
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
error!("Error converting specifier settings: {}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -376,6 +350,16 @@ impl Config {
|
|||
}
|
||||
}
|
||||
|
||||
/// Update all currently cached specifier settings
|
||||
pub async fn update_all_settings(&self) -> Result<(), AnyError> {
|
||||
self
|
||||
.tx
|
||||
.send(ConfigRequest::All)
|
||||
.await
|
||||
.map_err(|_| anyhow!("Error sending config update task."))
|
||||
}
|
||||
|
||||
/// Update a specific specifiers settings from the client.
|
||||
pub async fn update_specifier_settings(
|
||||
&self,
|
||||
specifier: &ModuleSpecifier,
|
||||
|
@ -387,14 +371,6 @@ impl Config {
|
|||
.await
|
||||
.map_err(|_| anyhow!("Error sending config update task."))
|
||||
}
|
||||
|
||||
pub async fn update_workspace_settings(&self) -> Result<(), AnyError> {
|
||||
self
|
||||
.tx
|
||||
.send(ConfigRequest::Workspace)
|
||||
.await
|
||||
.map_err(|_| anyhow!("Error sending config update task."))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -677,18 +677,36 @@ impl Inner {
|
|||
.performance
|
||||
.mark("did_change_configuration", Some(¶ms));
|
||||
|
||||
if self.config.client_capabilities.workspace_configuration {
|
||||
if let Err(err) = self.config.update_workspace_settings().await {
|
||||
error!("Error updating workspace settings: {}", err);
|
||||
}
|
||||
} else if let Some(config) = params
|
||||
.settings
|
||||
.as_object()
|
||||
.map(|settings| settings.get(SETTINGS_SECTION))
|
||||
.flatten()
|
||||
.cloned()
|
||||
{
|
||||
if let Err(err) = self.config.set_workspace_settings(config) {
|
||||
let maybe_config =
|
||||
if self.config.client_capabilities.workspace_configuration {
|
||||
let config_response = self
|
||||
.client
|
||||
.configuration(vec![ConfigurationItem {
|
||||
scope_uri: None,
|
||||
section: Some(SETTINGS_SECTION.to_string()),
|
||||
}])
|
||||
.await;
|
||||
if let Err(err) = self.config.update_all_settings().await {
|
||||
error!("Cannot request updating all settings: {}", err);
|
||||
}
|
||||
match config_response {
|
||||
Ok(value_vec) => value_vec.get(0).cloned(),
|
||||
Err(err) => {
|
||||
error!("Error getting workspace configuration: {}", err);
|
||||
None
|
||||
}
|
||||
}
|
||||
} else {
|
||||
params
|
||||
.settings
|
||||
.as_object()
|
||||
.map(|settings| settings.get(SETTINGS_SECTION))
|
||||
.flatten()
|
||||
.cloned()
|
||||
};
|
||||
|
||||
if let Some(value) = maybe_config {
|
||||
if let Err(err) = self.config.set_workspace_settings(value) {
|
||||
error!("failed to update settings: {}", err);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2125,3 +2125,93 @@ fn lsp_format_markdown() {
|
|||
);
|
||||
shutdown(&mut client);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lsp_configuration_did_change() {
|
||||
let _g = http_server();
|
||||
let mut client = init("initialize_params_did_config_change.json");
|
||||
did_open(
|
||||
&mut client,
|
||||
json!({
|
||||
"textDocument": {
|
||||
"uri": "file:///a/file.ts",
|
||||
"languageId": "typescript",
|
||||
"version": 1,
|
||||
"text": "import * as a from \"http://localhost:4545/x/a@\""
|
||||
}
|
||||
}),
|
||||
);
|
||||
client
|
||||
.write_notification(
|
||||
"workspace/didChangeConfiguration",
|
||||
json!({
|
||||
"settings": {}
|
||||
}),
|
||||
)
|
||||
.unwrap();
|
||||
let (id, method, _) = client.read_request::<Value>().unwrap();
|
||||
assert_eq!(method, "workspace/configuration");
|
||||
client
|
||||
.write_response(
|
||||
id,
|
||||
json!([{
|
||||
"enable": true,
|
||||
"codeLens": {
|
||||
"implementations": true,
|
||||
"references": true
|
||||
},
|
||||
"importMap": null,
|
||||
"lint": true,
|
||||
"suggest": {
|
||||
"autoImports": true,
|
||||
"completeFunctionCalls": false,
|
||||
"names": true,
|
||||
"paths": true,
|
||||
"imports": {
|
||||
"hosts": {
|
||||
"http://localhost:4545/": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"unstable": false
|
||||
}]),
|
||||
)
|
||||
.unwrap();
|
||||
let (maybe_res, maybe_err) = client
|
||||
.write_request(
|
||||
"textDocument/completion",
|
||||
json!({
|
||||
"textDocument": {
|
||||
"uri": "file:///a/file.ts"
|
||||
},
|
||||
"position": {
|
||||
"line": 0,
|
||||
"character": 46
|
||||
},
|
||||
"context": {
|
||||
"triggerKind": 2,
|
||||
"triggerCharacter": "@"
|
||||
}
|
||||
}),
|
||||
)
|
||||
.unwrap();
|
||||
assert!(maybe_err.is_none());
|
||||
if let Some(lsp::CompletionResponse::List(list)) = maybe_res {
|
||||
assert!(!list.is_incomplete);
|
||||
assert_eq!(list.items.len(), 3);
|
||||
} else {
|
||||
panic!("unexpected response");
|
||||
}
|
||||
let (maybe_res, maybe_err) = client
|
||||
.write_request(
|
||||
"completionItem/resolve",
|
||||
load_fixture("completion_resolve_params_registry.json"),
|
||||
)
|
||||
.unwrap();
|
||||
assert!(maybe_err.is_none());
|
||||
assert_eq!(
|
||||
maybe_res,
|
||||
Some(load_fixture("completion_resolve_response_registry.json"))
|
||||
);
|
||||
shutdown(&mut client);
|
||||
}
|
||||
|
|
62
cli/tests/lsp/initialize_params_did_config_change.json
Normal file
62
cli/tests/lsp/initialize_params_did_config_change.json
Normal file
|
@ -0,0 +1,62 @@
|
|||
{
|
||||
"processId": 0,
|
||||
"clientInfo": {
|
||||
"name": "test-harness",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"rootUri": null,
|
||||
"initializationOptions": {
|
||||
"enable": true,
|
||||
"codeLens": {
|
||||
"implementations": true,
|
||||
"references": true
|
||||
},
|
||||
"importMap": null,
|
||||
"lint": true,
|
||||
"suggest": {
|
||||
"autoImports": true,
|
||||
"completeFunctionCalls": false,
|
||||
"names": true,
|
||||
"paths": true,
|
||||
"imports": {
|
||||
"hosts": {
|
||||
"http://localhost:4545/": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"unstable": false
|
||||
},
|
||||
"capabilities": {
|
||||
"textDocument": {
|
||||
"codeAction": {
|
||||
"codeActionLiteralSupport": {
|
||||
"codeActionKind": {
|
||||
"valueSet": [
|
||||
"quickfix"
|
||||
]
|
||||
}
|
||||
},
|
||||
"isPreferredSupport": true,
|
||||
"dataSupport": true,
|
||||
"resolveSupport": {
|
||||
"properties": [
|
||||
"edit"
|
||||
]
|
||||
}
|
||||
},
|
||||
"foldingRange": {
|
||||
"lineFoldingOnly": true
|
||||
},
|
||||
"synchronization": {
|
||||
"dynamicRegistration": true,
|
||||
"willSave": true,
|
||||
"willSaveWaitUntil": true,
|
||||
"didSave": true
|
||||
}
|
||||
},
|
||||
"workspace": {
|
||||
"configuration": true,
|
||||
"workspaceFolders": true
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue