summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Sherret <dsherret@users.noreply.github.com>2023-07-10 21:03:19 -0400
committerGitHub <noreply@github.com>2023-07-10 21:03:19 -0400
commit0d8af65621be63a95d57611796a042e5ecf90f85 (patch)
tree38d5ffc95c33a7166e89a69938f7a053fcbab3af
parent96efe3c17628e1b77caa752e6de4654a786f4a8d (diff)
fix(lsp): exclude files in deno.json "exclude" (#19791)
Closes #19788
-rw-r--r--cli/lsp/config.rs95
-rw-r--r--cli/tests/integration/lsp_tests.rs131
2 files changed, 192 insertions, 34 deletions
diff --git a/cli/lsp/config.rs b/cli/lsp/config.rs
index 4d008a290..298c86a55 100644
--- a/cli/lsp/config.rs
+++ b/cli/lsp/config.rs
@@ -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>>> {
diff --git a/cli/tests/integration/lsp_tests.rs b/cli/tests/integration/lsp_tests.rs
index 467fa85a5..eb5885529 100644
--- a/cli/tests/integration/lsp_tests.rs
+++ b/cli/tests/integration/lsp_tests.rs
@@ -1213,6 +1213,137 @@ fn lsp_workspace_enable_paths() {
}
#[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();
let mut client = context.new_lsp_command().build();