mirror of
https://github.com/denoland/deno.git
synced 2025-01-22 06:09:25 -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 {
|
enum ConfigRequest {
|
||||||
|
All,
|
||||||
Specifier(ModuleSpecifier, ModuleSpecifier),
|
Specifier(ModuleSpecifier, ModuleSpecifier),
|
||||||
Workspace,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone)]
|
#[derive(Debug, Default, Clone)]
|
||||||
|
@ -197,12 +197,8 @@ impl Config {
|
||||||
loop {
|
loop {
|
||||||
match rx.recv().await {
|
match rx.recv().await {
|
||||||
None => break,
|
None => break,
|
||||||
Some(ConfigRequest::Workspace) => {
|
Some(ConfigRequest::All) => {
|
||||||
let mut items = vec![lsp::ConfigurationItem {
|
let (specifier_uri_map, items): (
|
||||||
scope_uri: None,
|
|
||||||
section: Some(SETTINGS_SECTION.to_string()),
|
|
||||||
}];
|
|
||||||
let (specifier_uri_map, mut specifier_items): (
|
|
||||||
Vec<(ModuleSpecifier, ModuleSpecifier)>,
|
Vec<(ModuleSpecifier, ModuleSpecifier)>,
|
||||||
Vec<lsp::ConfigurationItem>,
|
Vec<lsp::ConfigurationItem>,
|
||||||
) = {
|
) = {
|
||||||
|
@ -223,40 +219,18 @@ impl Config {
|
||||||
.collect(),
|
.collect(),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
items.append(&mut specifier_items);
|
|
||||||
if let Ok(configs) = client.configuration(items).await {
|
if let Ok(configs) = client.configuration(items).await {
|
||||||
let mut settings = settings_ref.write().unwrap();
|
let mut settings = settings_ref.write().unwrap();
|
||||||
for (i, value) in configs.into_iter().enumerate() {
|
for (i, value) in configs.into_iter().enumerate() {
|
||||||
match i {
|
match serde_json::from_value::<SpecifierSettings>(value) {
|
||||||
0 => {
|
Ok(specifier_settings) => {
|
||||||
match serde_json::from_value::<WorkspaceSettings>(value) {
|
let (specifier, uri) = specifier_uri_map[i].clone();
|
||||||
Ok(workspace_settings) => {
|
settings
|
||||||
settings.workspace = workspace_settings;
|
.specifiers
|
||||||
}
|
.insert(specifier, (uri, specifier_settings));
|
||||||
Err(err) => {
|
|
||||||
error!(
|
|
||||||
"Error converting workspace settings: {}",
|
|
||||||
err
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => {
|
Err(err) => {
|
||||||
match serde_json::from_value::<SpecifierSettings>(value) {
|
error!("Error converting specifier settings: {}", err);
|
||||||
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
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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(
|
pub async fn update_specifier_settings(
|
||||||
&self,
|
&self,
|
||||||
specifier: &ModuleSpecifier,
|
specifier: &ModuleSpecifier,
|
||||||
|
@ -387,14 +371,6 @@ impl Config {
|
||||||
.await
|
.await
|
||||||
.map_err(|_| anyhow!("Error sending config update task."))
|
.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)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -677,18 +677,36 @@ impl Inner {
|
||||||
.performance
|
.performance
|
||||||
.mark("did_change_configuration", Some(¶ms));
|
.mark("did_change_configuration", Some(¶ms));
|
||||||
|
|
||||||
if self.config.client_capabilities.workspace_configuration {
|
let maybe_config =
|
||||||
if let Err(err) = self.config.update_workspace_settings().await {
|
if self.config.client_capabilities.workspace_configuration {
|
||||||
error!("Error updating workspace settings: {}", err);
|
let config_response = self
|
||||||
}
|
.client
|
||||||
} else if let Some(config) = params
|
.configuration(vec![ConfigurationItem {
|
||||||
.settings
|
scope_uri: None,
|
||||||
.as_object()
|
section: Some(SETTINGS_SECTION.to_string()),
|
||||||
.map(|settings| settings.get(SETTINGS_SECTION))
|
}])
|
||||||
.flatten()
|
.await;
|
||||||
.cloned()
|
if let Err(err) = self.config.update_all_settings().await {
|
||||||
{
|
error!("Cannot request updating all settings: {}", err);
|
||||||
if let Err(err) = self.config.set_workspace_settings(config) {
|
}
|
||||||
|
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);
|
error!("failed to update settings: {}", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2125,3 +2125,93 @@ fn lsp_format_markdown() {
|
||||||
);
|
);
|
||||||
shutdown(&mut client);
|
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