mirror of
https://github.com/denoland/deno.git
synced 2024-11-21 15:04:11 -05:00
parent
96efe3c176
commit
0d8af65621
2 changed files with 192 additions and 34 deletions
|
@ -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>>> {
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue