1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-21 15:04:11 -05:00

fix(lsp): exclude files in deno.json "exclude" (#19791)

Closes #19788
This commit is contained in:
David Sherret 2023-07-10 21:03:19 -04:00 committed by GitHub
parent 96efe3c176
commit 0d8af65621
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 192 additions and 34 deletions

View file

@ -403,27 +403,19 @@ impl WorkspaceSettings {
pub struct ConfigSnapshot {
pub client_capabilities: ClientCapabilities,
pub enabled_paths: HashMap<Url, Vec<Url>>,
pub excluded_paths: Option<Vec<Url>>,
pub settings: Settings,
}
impl ConfigSnapshot {
/// Determine if the provided specifier is enabled or not.
pub fn specifier_enabled(&self, specifier: &ModuleSpecifier) -> bool {
if !self.enabled_paths.is_empty() {
let specifier_str = specifier.as_str();
for (workspace, enabled_paths) in self.enabled_paths.iter() {
if specifier_str.starts_with(workspace.as_str()) {
return enabled_paths
.iter()
.any(|path| specifier_str.starts_with(path.as_str()));
}
}
}
if let Some(settings) = self.settings.specifiers.get(specifier) {
settings.enable
} else {
self.settings.workspace.enable
}
specifier_enabled(
&self.enabled_paths,
self.excluded_paths.as_ref(),
&self.settings,
specifier,
)
}
}
@ -436,11 +428,12 @@ pub struct Settings {
/// Contains the config file and dependent information.
#[derive(Debug)]
struct LspConfigFileInfo {
pub config_file: ConfigFile,
config_file: ConfigFile,
/// An optional deno.lock file, which is resolved relative to the config file.
pub maybe_lockfile: Option<Arc<Mutex<Lockfile>>>,
maybe_lockfile: Option<Arc<Mutex<Lockfile>>>,
/// The canonicalized node_modules directory, which is found relative to the config file.
pub maybe_node_modules_dir: Option<PathBuf>,
maybe_node_modules_dir: Option<PathBuf>,
excluded_paths: Vec<Url>,
}
#[derive(Debug)]
@ -494,6 +487,15 @@ impl Config {
self.maybe_config_file_info = Some(LspConfigFileInfo {
maybe_lockfile: resolve_lockfile_from_config(&config_file),
maybe_node_modules_dir: resolve_node_modules_dir(&config_file),
excluded_paths: config_file
.to_files_config()
.ok()
.flatten()
.map(|c| c.exclude)
.unwrap_or_default()
.into_iter()
.filter_map(|path| ModuleSpecifier::from_file_path(path).ok())
.collect(),
config_file,
});
}
@ -517,6 +519,10 @@ impl Config {
Arc::new(ConfigSnapshot {
client_capabilities: self.client_capabilities.clone(),
enabled_paths: self.enabled_paths.clone(),
excluded_paths: self
.maybe_config_file_info
.as_ref()
.map(|i| i.excluded_paths.clone()),
settings: self.settings.clone(),
})
}
@ -526,22 +532,15 @@ impl Config {
}
pub fn specifier_enabled(&self, specifier: &ModuleSpecifier) -> bool {
if !self.enabled_paths.is_empty() {
let specifier_str = specifier.as_str();
for (workspace, enabled_paths) in self.enabled_paths.iter() {
if specifier_str.starts_with(workspace.as_str()) {
return enabled_paths
.iter()
.any(|path| specifier_str.starts_with(path.as_str()));
}
}
}
self
.settings
.specifiers
.get(specifier)
.map(|settings| settings.enable)
.unwrap_or_else(|| self.settings.workspace.enable)
specifier_enabled(
&self.enabled_paths,
self
.maybe_config_file_info
.as_ref()
.map(|i| &i.excluded_paths),
&self.settings,
specifier,
)
}
/// Gets the directories or specifically enabled file paths based on the
@ -712,6 +711,34 @@ impl Config {
}
}
fn specifier_enabled(
enabled_paths: &HashMap<Url, Vec<Url>>,
excluded_paths: Option<&Vec<Url>>,
settings: &Settings,
specifier: &Url,
) -> bool {
let specifier_str = specifier.as_str();
for (workspace, enabled_paths) in enabled_paths.iter() {
if specifier_str.starts_with(workspace.as_str()) {
return enabled_paths
.iter()
.any(|path| specifier_str.starts_with(path.as_str()));
}
}
if let Some(excluded_paths) = excluded_paths {
for excluded_path in excluded_paths {
if specifier_str.starts_with(excluded_path.as_str()) {
return false;
}
}
}
settings
.specifiers
.get(specifier)
.map(|settings| settings.enable)
.unwrap_or_else(|| settings.workspace.enable)
}
fn resolve_lockfile_from_config(
config_file: &ConfigFile,
) -> Option<Arc<Mutex<Lockfile>>> {

View file

@ -1212,6 +1212,137 @@ fn lsp_workspace_enable_paths() {
run_test(false);
}
#[test]
fn lsp_exclude_config() {
let context = TestContextBuilder::new().use_temp_cwd().build();
let temp_dir = context.temp_dir();
temp_dir.create_dir_all("other");
temp_dir.write(
"other/shared.ts",
// this should not be found in the "find references" since this file is excluded
"import { a } from '../worker/shared.ts'; console.log(a);",
);
temp_dir.create_dir_all("worker");
temp_dir.write("worker/shared.ts", "export const a = 1");
temp_dir.write(
"deno.json",
r#"{
"exclude": ["other"],
}"#,
);
let root_specifier = temp_dir.uri();
let mut client = context.new_lsp_command().build();
client.initialize_default();
client.did_open(json!({
"textDocument": {
"uri": root_specifier.join("./other/file.ts").unwrap(),
"languageId": "typescript",
"version": 1,
"text": "console.log(Date.now());\n"
}
}));
client.did_open(json!({
"textDocument": {
"uri": root_specifier.join("./worker/file.ts").unwrap(),
"languageId": "typescript",
"version": 1,
"text": concat!(
"console.log(Date.now());\n",
"import { a } from './shared.ts';\n",
"a;\n",
),
}
}));
client.did_open(json!({
"textDocument": {
"uri": root_specifier.join("./worker/subdir/file.ts").unwrap(),
"languageId": "typescript",
"version": 1,
"text": "console.log(Date.now());\n"
}
}));
let res = client.write_request(
"textDocument/hover",
json!({
"textDocument": {
"uri": root_specifier.join("./other/file.ts").unwrap(),
},
"position": { "line": 0, "character": 19 }
}),
);
assert_eq!(res, json!(null));
let res = client.write_request(
"textDocument/hover",
json!({
"textDocument": {
"uri": root_specifier.join("./worker/file.ts").unwrap(),
},
"position": { "line": 0, "character": 19 }
}),
);
assert_eq!(
res,
json!({
"contents": [
{
"language": "typescript",
"value": "(method) DateConstructor.now(): number",
},
"Returns the number of milliseconds elapsed since midnight, January 1, 1970 Universal Coordinated Time (UTC)."
],
"range": {
"start": { "line": 0, "character": 17, },
"end": { "line": 0, "character": 20, }
}
})
);
// check that the file system documents were auto-discovered
let res = client.write_request(
"textDocument/references",
json!({
"textDocument": {
"uri": root_specifier.join("./worker/file.ts").unwrap(),
},
"position": { "line": 2, "character": 0 },
"context": {
"includeDeclaration": true
}
}),
);
assert_eq!(
res,
json!([{
"uri": root_specifier.join("./worker/file.ts").unwrap(),
"range": {
"start": { "line": 1, "character": 9 },
"end": { "line": 1, "character": 10 }
}
}, {
"uri": root_specifier.join("./worker/file.ts").unwrap(),
"range": {
"start": { "line": 2, "character": 0 },
"end": { "line": 2, "character": 1 }
}
}, {
"uri": root_specifier.join("./worker/shared.ts").unwrap(),
"range": {
"start": { "line": 0, "character": 13 },
"end": { "line": 0, "character": 14 }
}
}])
);
client.shutdown();
}
#[test]
fn lsp_hover_unstable_disabled() {
let context = TestContextBuilder::new().use_temp_cwd().build();