mirror of
https://github.com/denoland/deno.git
synced 2024-12-23 07:44:48 -05:00
fix(lsp): inherit workspace-root-only fields in members (#24440)
This commit is contained in:
parent
b338b541ac
commit
d472c48b38
2 changed files with 442 additions and 23 deletions
|
@ -1299,16 +1299,27 @@ impl ConfigData {
|
|||
}
|
||||
};
|
||||
|
||||
let vendor_dir = config_file.as_ref().and_then(|c| {
|
||||
if c.vendor() == Some(true) {
|
||||
Some(c.specifier.to_file_path().ok()?.parent()?.join("vendor"))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
let vendor_dir = if let Some(workspace_root) = workspace_root {
|
||||
workspace_root.vendor_dir.clone()
|
||||
} else {
|
||||
config_file.as_ref().and_then(|c| {
|
||||
if c.vendor() == Some(true) {
|
||||
Some(c.specifier.to_file_path().ok()?.parent()?.join("vendor"))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
// Load lockfile
|
||||
let lockfile = config_file.as_ref().and_then(resolve_lockfile_from_config);
|
||||
let lockfile = if let Some(workspace_root) = workspace_root {
|
||||
workspace_root.lockfile.clone()
|
||||
} else {
|
||||
config_file
|
||||
.as_ref()
|
||||
.and_then(resolve_lockfile_from_config)
|
||||
.map(Arc::new)
|
||||
};
|
||||
if let Some(lockfile) = &lockfile {
|
||||
if let Ok(specifier) = ModuleSpecifier::from_file_path(&lockfile.filename)
|
||||
{
|
||||
|
@ -1376,23 +1387,31 @@ impl ConfigData {
|
|||
})
|
||||
.map(|(r, _)| r)
|
||||
.ok();
|
||||
let byonm = std::env::var("DENO_UNSTABLE_BYONM").is_ok()
|
||||
|| config_file
|
||||
.as_ref()
|
||||
.map(|c| c.has_unstable("byonm"))
|
||||
.unwrap_or(false)
|
||||
|| (*DENO_FUTURE
|
||||
&& package_json.is_some()
|
||||
&& config_file
|
||||
let byonm = if let Some(workspace_root) = workspace_root {
|
||||
workspace_root.byonm
|
||||
} else {
|
||||
std::env::var("DENO_UNSTABLE_BYONM").is_ok()
|
||||
|| config_file
|
||||
.as_ref()
|
||||
.map(|c| c.json.node_modules_dir.is_none())
|
||||
.unwrap_or(true));
|
||||
.map(|c| c.has_unstable("byonm"))
|
||||
.unwrap_or(false)
|
||||
|| (*DENO_FUTURE
|
||||
&& package_json.is_some()
|
||||
&& config_file
|
||||
.as_ref()
|
||||
.map(|c| c.json.node_modules_dir.is_none())
|
||||
.unwrap_or(true))
|
||||
};
|
||||
if byonm {
|
||||
lsp_log!(" Enabled 'bring your own node_modules'.");
|
||||
}
|
||||
let node_modules_dir = config_file
|
||||
.as_ref()
|
||||
.and_then(|c| resolve_node_modules_dir(c, byonm));
|
||||
let node_modules_dir = if let Some(workspace_root) = workspace_root {
|
||||
workspace_root.node_modules_dir.clone()
|
||||
} else {
|
||||
config_file
|
||||
.as_ref()
|
||||
.and_then(|c| resolve_node_modules_dir(c, byonm))
|
||||
};
|
||||
|
||||
// Load import map
|
||||
let mut import_map = None;
|
||||
|
@ -1547,7 +1566,7 @@ impl ConfigData {
|
|||
byonm,
|
||||
node_modules_dir,
|
||||
vendor_dir,
|
||||
lockfile: lockfile.map(Arc::new),
|
||||
lockfile,
|
||||
package_json: package_json.map(Arc::new),
|
||||
npmrc,
|
||||
import_map,
|
||||
|
|
|
@ -12366,7 +12366,7 @@ fn lsp_deno_json_scopes_import_map() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn lsp_deno_json_scopes_vendor_dirs() {
|
||||
fn lsp_deno_json_scopes_vendor_dir() {
|
||||
let context = TestContextBuilder::new()
|
||||
.use_http_server()
|
||||
.use_temp_cwd()
|
||||
|
@ -12550,6 +12550,194 @@ fn lsp_deno_json_scopes_vendor_dirs() {
|
|||
client.shutdown();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lsp_deno_json_scopes_node_modules_dir() {
|
||||
let context = TestContextBuilder::new()
|
||||
.use_http_server()
|
||||
.use_temp_cwd()
|
||||
.build();
|
||||
let temp_dir = context.temp_dir();
|
||||
temp_dir.create_dir_all("project1");
|
||||
temp_dir.create_dir_all("project2/project3");
|
||||
temp_dir.write(
|
||||
"project1/deno.json",
|
||||
json!({
|
||||
"nodeModulesDir": true,
|
||||
})
|
||||
.to_string(),
|
||||
);
|
||||
temp_dir.write(
|
||||
"project2/deno.json",
|
||||
json!({
|
||||
"nodeModulesDir": true,
|
||||
})
|
||||
.to_string(),
|
||||
);
|
||||
temp_dir.write(
|
||||
"project2/project3/deno.json",
|
||||
json!({
|
||||
"nodeModulesDir": true,
|
||||
})
|
||||
.to_string(),
|
||||
);
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
"textDocument": {
|
||||
"uri": temp_dir.uri().join("project1/file.ts").unwrap(),
|
||||
"languageId": "typescript",
|
||||
"version": 1,
|
||||
"text": "import \"npm:@denotest/add@1\";\n",
|
||||
},
|
||||
}));
|
||||
client.write_request(
|
||||
"workspace/executeCommand",
|
||||
json!({
|
||||
"command": "deno.cache",
|
||||
"arguments": [[], temp_dir.uri().join("project1/file.ts").unwrap()],
|
||||
}),
|
||||
);
|
||||
let res = client.write_request(
|
||||
"textDocument/definition",
|
||||
json!({
|
||||
"textDocument": {
|
||||
"uri": temp_dir.uri().join("project1/file.ts").unwrap(),
|
||||
},
|
||||
"position": { "line": 0, "character": 7 },
|
||||
}),
|
||||
);
|
||||
// The temp dir is symlinked in macos, and `node_modules` is canonicalized.
|
||||
let canon_temp_dir =
|
||||
Url::from_directory_path(temp_dir.path().canonicalize()).unwrap();
|
||||
assert_eq!(
|
||||
res,
|
||||
json!([{
|
||||
"targetUri": canon_temp_dir.join("project1/node_modules/.deno/@denotest+add@1.0.0/node_modules/@denotest/add/index.d.ts").unwrap(),
|
||||
"targetRange": {
|
||||
"start": {
|
||||
"line": 0,
|
||||
"character": 0,
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"character": 0,
|
||||
},
|
||||
},
|
||||
"targetSelectionRange": {
|
||||
"start": {
|
||||
"line": 0,
|
||||
"character": 0,
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"character": 0,
|
||||
},
|
||||
},
|
||||
}]),
|
||||
);
|
||||
client.did_open(json!({
|
||||
"textDocument": {
|
||||
"uri": temp_dir.uri().join("project2/file.ts").unwrap(),
|
||||
"languageId": "typescript",
|
||||
"version": 1,
|
||||
"text": "import \"npm:@denotest/add@1\";\n",
|
||||
},
|
||||
}));
|
||||
client.write_request(
|
||||
"workspace/executeCommand",
|
||||
json!({
|
||||
"command": "deno.cache",
|
||||
"arguments": [[], temp_dir.uri().join("project2/file.ts").unwrap()],
|
||||
}),
|
||||
);
|
||||
let res = client.write_request(
|
||||
"textDocument/definition",
|
||||
json!({
|
||||
"textDocument": {
|
||||
"uri": temp_dir.uri().join("project2/file.ts").unwrap(),
|
||||
},
|
||||
"position": { "line": 0, "character": 7 },
|
||||
}),
|
||||
);
|
||||
assert_eq!(
|
||||
res,
|
||||
json!([{
|
||||
"targetUri": canon_temp_dir.join("project2/node_modules/.deno/@denotest+add@1.0.0/node_modules/@denotest/add/index.d.ts").unwrap(),
|
||||
"targetRange": {
|
||||
"start": {
|
||||
"line": 0,
|
||||
"character": 0,
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"character": 0,
|
||||
},
|
||||
},
|
||||
"targetSelectionRange": {
|
||||
"start": {
|
||||
"line": 0,
|
||||
"character": 0,
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"character": 0,
|
||||
},
|
||||
},
|
||||
}]),
|
||||
);
|
||||
client.did_open(json!({
|
||||
"textDocument": {
|
||||
"uri": temp_dir.uri().join("project2/project3/file.ts").unwrap(),
|
||||
"languageId": "typescript",
|
||||
"version": 1,
|
||||
"text": "import \"npm:@denotest/add@1\";\n",
|
||||
},
|
||||
}));
|
||||
client.write_request(
|
||||
"workspace/executeCommand",
|
||||
json!({
|
||||
"command": "deno.cache",
|
||||
"arguments": [[], temp_dir.uri().join("project2/project3/file.ts").unwrap()],
|
||||
}),
|
||||
);
|
||||
let res = client.write_request(
|
||||
"textDocument/definition",
|
||||
json!({
|
||||
"textDocument": {
|
||||
"uri": temp_dir.uri().join("project2/project3/file.ts").unwrap(),
|
||||
},
|
||||
"position": { "line": 0, "character": 7 },
|
||||
}),
|
||||
);
|
||||
assert_eq!(
|
||||
res,
|
||||
json!([{
|
||||
"targetUri": canon_temp_dir.join("project2/project3/node_modules/.deno/@denotest+add@1.0.0/node_modules/@denotest/add/index.d.ts").unwrap(),
|
||||
"targetRange": {
|
||||
"start": {
|
||||
"line": 0,
|
||||
"character": 0,
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"character": 0,
|
||||
},
|
||||
},
|
||||
"targetSelectionRange": {
|
||||
"start": {
|
||||
"line": 0,
|
||||
"character": 0,
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"character": 0,
|
||||
},
|
||||
},
|
||||
}]),
|
||||
);
|
||||
client.shutdown();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lsp_deno_json_scopes_ts_config() {
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
|
@ -13369,6 +13557,218 @@ fn lsp_deno_json_workspace_import_map() {
|
|||
client.shutdown();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lsp_workspace_lockfile() {
|
||||
let context = TestContextBuilder::new()
|
||||
.use_http_server()
|
||||
.use_temp_cwd()
|
||||
.build();
|
||||
let temp_dir = context.temp_dir();
|
||||
temp_dir.create_dir_all("project1/project2");
|
||||
temp_dir.write(
|
||||
"project1/deno.json",
|
||||
json!({
|
||||
"workspace": ["project2"],
|
||||
})
|
||||
.to_string(),
|
||||
);
|
||||
temp_dir.write("project1/deno.lock", json!({
|
||||
"version": "3",
|
||||
"redirects": {
|
||||
"http://localhost:4545/subdir/mod1.ts": "http://localhost:4545/subdir/mod2.ts",
|
||||
},
|
||||
"remote": {},
|
||||
}).to_string());
|
||||
temp_dir.write("project1/project2/deno.json", json!({}).to_string());
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
"textDocument": {
|
||||
"uri": temp_dir.uri().join("project1/project2/file.ts").unwrap(),
|
||||
"languageId": "typescript",
|
||||
"version": 1,
|
||||
"text": "import \"http://localhost:4545/subdir/mod1.ts\";\n",
|
||||
},
|
||||
}));
|
||||
client.write_request(
|
||||
"workspace/executeCommand",
|
||||
json!({
|
||||
"command": "deno.cache",
|
||||
"arguments": [[], temp_dir.uri().join("project1/project2/file.ts").unwrap()],
|
||||
}),
|
||||
);
|
||||
client.read_diagnostics();
|
||||
let res = client.write_request(
|
||||
"textDocument/definition",
|
||||
json!({
|
||||
"textDocument": { "uri": temp_dir.uri().join("project1/project2/file.ts").unwrap() },
|
||||
"position": { "line": 0, "character": 7 },
|
||||
}),
|
||||
);
|
||||
assert_eq!(
|
||||
res,
|
||||
json!([{
|
||||
"targetUri": "deno:/http/localhost%3A4545/subdir/mod2.ts",
|
||||
"targetRange": {
|
||||
"start": { "line": 0, "character": 0 },
|
||||
"end": { "line": 1, "character": 0 },
|
||||
},
|
||||
"targetSelectionRange": {
|
||||
"start": { "line": 0, "character": 0 },
|
||||
"end": { "line": 1, "character": 0 },
|
||||
},
|
||||
}]),
|
||||
);
|
||||
client.shutdown();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lsp_deno_json_workspace_vendor_dir() {
|
||||
let context = TestContextBuilder::new()
|
||||
.use_http_server()
|
||||
.use_temp_cwd()
|
||||
.build();
|
||||
let temp_dir = context.temp_dir();
|
||||
temp_dir.create_dir_all("project1/project2");
|
||||
temp_dir.write(
|
||||
"project1/deno.json",
|
||||
json!({
|
||||
"workspace": ["project2"],
|
||||
"vendor": true,
|
||||
})
|
||||
.to_string(),
|
||||
);
|
||||
temp_dir.write("project1/project2/deno.json", json!({}).to_string());
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
"textDocument": {
|
||||
"uri": temp_dir.uri().join("project1/project2/file.ts").unwrap(),
|
||||
"languageId": "typescript",
|
||||
"version": 1,
|
||||
"text": "import \"http://localhost:4545/subdir/mod1.ts\";\n",
|
||||
},
|
||||
}));
|
||||
client.write_request(
|
||||
"workspace/executeCommand",
|
||||
json!({
|
||||
"command": "deno.cache",
|
||||
"arguments": [[], temp_dir.uri().join("project1/project2/file.ts").unwrap()],
|
||||
}),
|
||||
);
|
||||
let res = client.write_request(
|
||||
"textDocument/definition",
|
||||
json!({
|
||||
"textDocument": {
|
||||
"uri": temp_dir.uri().join("project1/project2/file.ts").unwrap(),
|
||||
},
|
||||
"position": { "line": 0, "character": 7 },
|
||||
}),
|
||||
);
|
||||
assert_eq!(
|
||||
res,
|
||||
json!([{
|
||||
"targetUri": temp_dir.uri().join("project1/vendor/http_localhost_4545/subdir/mod1.ts").unwrap(),
|
||||
"targetRange": {
|
||||
"start": {
|
||||
"line": 0,
|
||||
"character": 0,
|
||||
},
|
||||
"end": {
|
||||
"line": 17,
|
||||
"character": 0,
|
||||
},
|
||||
},
|
||||
"targetSelectionRange": {
|
||||
"start": {
|
||||
"line": 0,
|
||||
"character": 0,
|
||||
},
|
||||
"end": {
|
||||
"line": 17,
|
||||
"character": 0,
|
||||
},
|
||||
},
|
||||
}]),
|
||||
);
|
||||
client.shutdown();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lsp_deno_json_workspace_node_modules_dir() {
|
||||
let context = TestContextBuilder::new()
|
||||
.use_http_server()
|
||||
.use_temp_cwd()
|
||||
.build();
|
||||
let temp_dir = context.temp_dir();
|
||||
temp_dir.create_dir_all("project1/project2");
|
||||
temp_dir.write(
|
||||
"project1/deno.json",
|
||||
json!({
|
||||
"workspace": ["project2"],
|
||||
"nodeModulesDir": true,
|
||||
})
|
||||
.to_string(),
|
||||
);
|
||||
temp_dir.write("project1/project2/deno.json", json!({}).to_string());
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
"textDocument": {
|
||||
"uri": temp_dir.uri().join("project1/project2/file.ts").unwrap(),
|
||||
"languageId": "typescript",
|
||||
"version": 1,
|
||||
"text": "import \"npm:@denotest/add@1\";\n",
|
||||
},
|
||||
}));
|
||||
client.write_request(
|
||||
"workspace/executeCommand",
|
||||
json!({
|
||||
"command": "deno.cache",
|
||||
"arguments": [[], temp_dir.uri().join("project1/project2/file.ts").unwrap()],
|
||||
}),
|
||||
);
|
||||
let res = client.write_request(
|
||||
"textDocument/definition",
|
||||
json!({
|
||||
"textDocument": {
|
||||
"uri": temp_dir.uri().join("project1/project2/file.ts").unwrap(),
|
||||
},
|
||||
"position": { "line": 0, "character": 7 },
|
||||
}),
|
||||
);
|
||||
// The temp dir is symlinked in macos, and `node_modules` is canonicalized.
|
||||
let canon_temp_dir =
|
||||
Url::from_directory_path(temp_dir.path().canonicalize()).unwrap();
|
||||
assert_eq!(
|
||||
res,
|
||||
json!([{
|
||||
"targetUri": canon_temp_dir.join("project1/node_modules/.deno/@denotest+add@1.0.0/node_modules/@denotest/add/index.d.ts").unwrap(),
|
||||
"targetRange": {
|
||||
"start": {
|
||||
"line": 0,
|
||||
"character": 0,
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"character": 0,
|
||||
},
|
||||
},
|
||||
"targetSelectionRange": {
|
||||
"start": {
|
||||
"line": 0,
|
||||
"character": 0,
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"character": 0,
|
||||
},
|
||||
},
|
||||
}]),
|
||||
);
|
||||
client.shutdown();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lsp_deno_json_workspace_jsr_resolution() {
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
|
|
Loading…
Reference in a new issue