diff --git a/cli/lsp/cache.rs b/cli/lsp/cache.rs index e6186030a11079..5dae38c206f489 100644 --- a/cli/lsp/cache.rs +++ b/cli/lsp/cache.rs @@ -184,4 +184,13 @@ impl LspCache { .as_ref()?; vendor.get_remote_url(&path) } + + pub fn is_valid_file_referrer(&self, specifier: &ModuleSpecifier) -> bool { + if let Ok(path) = specifier_to_file_path(specifier) { + if !path.starts_with(&self.deno_dir().root) { + return true; + } + } + false + } } diff --git a/cli/lsp/documents.rs b/cli/lsp/documents.rs index 29308e9f7528d3..05f9be718ae3fb 100644 --- a/cli/lsp/documents.rs +++ b/cli/lsp/documents.rs @@ -318,7 +318,7 @@ impl Document { file_referrer: Option, ) -> Arc { let file_referrer = Some(&specifier) - .filter(|s| s.scheme() == "file") + .filter(|s| cache.is_valid_file_referrer(s)) .cloned() .or(file_referrer); let media_type = resolve_media_type( @@ -804,7 +804,7 @@ impl FileSystemDocuments { file_referrer: Option<&ModuleSpecifier>, ) -> Option> { let file_referrer = Some(specifier) - .filter(|s| s.scheme() == "file") + .filter(|s| cache.is_valid_file_referrer(s)) .or(file_referrer); let new_fs_version = calculate_fs_version(cache, specifier, file_referrer); let old_doc = self.docs.get(specifier).map(|v| v.value().clone()); @@ -1051,13 +1051,16 @@ impl Documents { &self, specifier: &'a ModuleSpecifier, ) -> Option> { - if specifier.scheme() == "file" { - Some(Cow::Borrowed(specifier)) - } else { - self - .get(specifier) - .and_then(|d| d.file_referrer().cloned().map(Cow::Owned)) + if self.is_valid_file_referrer(specifier) { + return Some(Cow::Borrowed(specifier)); } + self + .get(specifier) + .and_then(|d| d.file_referrer().cloned().map(Cow::Owned)) + } + + pub fn is_valid_file_referrer(&self, specifier: &ModuleSpecifier) -> bool { + self.cache.is_valid_file_referrer(specifier) } /// Return `true` if the provided specifier can be resolved to a document, @@ -1447,20 +1450,25 @@ impl Documents { return Some((specifier.clone(), MediaType::Dts)); } } - - if let Ok(npm_ref) = NpmPackageReqReference::from_specifier(specifier) { - return self - .resolver - .npm_to_file_url(&npm_ref, referrer, file_referrer); + let mut specifier = specifier.clone(); + let mut media_type = None; + if let Ok(npm_ref) = NpmPackageReqReference::from_specifier(&specifier) { + let (s, mt) = + self + .resolver + .npm_to_file_url(&npm_ref, referrer, file_referrer)?; + specifier = s; + media_type = Some(mt); } - let Some(doc) = self.get_or_load(specifier, referrer) else { - return Some((specifier.clone(), MediaType::from_specifier(specifier))); + let Some(doc) = self.get_or_load(&specifier, referrer) else { + let media_type = + media_type.unwrap_or_else(|| MediaType::from_specifier(&specifier)); + return Some((specifier, media_type)); }; if let Some(types) = doc.maybe_types_dependency().maybe_specifier() { - self.resolve_dependency(types, specifier, file_referrer) + self.resolve_dependency(types, &specifier, file_referrer) } else { - let media_type = doc.media_type(); - Some((doc.specifier().clone(), media_type)) + Some((doc.specifier().clone(), doc.media_type())) } } } @@ -1593,7 +1601,8 @@ mod tests { async fn setup() -> (Documents, LspCache, TempDir) { let temp_dir = TempDir::new(); - let cache = LspCache::new(Some(temp_dir.uri())); + temp_dir.create_dir_all(".deno_dir"); + let cache = LspCache::new(Some(temp_dir.uri().join(".deno_dir").unwrap())); let config = Config::default(); let resolver = Arc::new(LspResolver::from_config(&config, &cache, None).await); diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs index 7d8213a244be25..35bfa7f783f599 100644 --- a/cli/lsp/language_server.rs +++ b/cli/lsp/language_server.rs @@ -1058,8 +1058,10 @@ impl Inner { params.text_document.uri ); } - let file_referrer = (params.text_document.uri.scheme() == "file") - .then(|| params.text_document.uri.clone()); + let file_referrer = (self + .documents + .is_valid_file_referrer(¶ms.text_document.uri)) + .then(|| params.text_document.uri.clone()); let specifier = self .url_map .normalize_url(¶ms.text_document.uri, LspUrlKind::File); @@ -1308,8 +1310,10 @@ impl Inner { &self, params: DocumentFormattingParams, ) -> LspResult>> { - let file_referrer = (params.text_document.uri.scheme() == "file") - .then(|| params.text_document.uri.clone()); + let file_referrer = (self + .documents + .is_valid_file_referrer(¶ms.text_document.uri)) + .then(|| params.text_document.uri.clone()); let mut specifier = self .url_map .normalize_url(¶ms.text_document.uri, LspUrlKind::File); diff --git a/cli/lsp/tsc.rs b/cli/lsp/tsc.rs index 3239ba70079009..4ef0d4e64e8012 100644 --- a/cli/lsp/tsc.rs +++ b/cli/lsp/tsc.rs @@ -463,7 +463,7 @@ impl TsServer { let mut diagnostics_map = IndexMap::with_capacity(specifiers.len()); let mut specifiers_by_scope = BTreeMap::new(); for specifier in specifiers { - let scope = if specifier.scheme() == "file" { + let scope = if snapshot.documents.is_valid_file_referrer(&specifier) { snapshot .config .tree