diff options
Diffstat (limited to 'cli/lsp/documents.rs')
-rw-r--r-- | cli/lsp/documents.rs | 705 |
1 files changed, 324 insertions, 381 deletions
diff --git a/cli/lsp/documents.rs b/cli/lsp/documents.rs index ce7e4e36f..9892eab1f 100644 --- a/cli/lsp/documents.rs +++ b/cli/lsp/documents.rs @@ -2,6 +2,7 @@ use super::text::LineIndex; use super::tsc; +use super::tsc::AssetDocument; use crate::config_file::ConfigFile; use crate::file_fetcher::get_source_from_bytes; @@ -134,6 +135,62 @@ impl IndexValid { } } +#[derive(Debug, Clone)] +pub(crate) enum AssetOrDocument { + Document(Document), + Asset(AssetDocument), +} + +impl AssetOrDocument { + pub fn document(&self) -> Option<&Document> { + match self { + AssetOrDocument::Asset(_) => None, + AssetOrDocument::Document(doc) => Some(doc), + } + } + + pub fn text(&self) -> Arc<String> { + match self { + AssetOrDocument::Asset(a) => a.text(), + AssetOrDocument::Document(d) => d.0.text_info.text(), + } + } + + pub fn line_index(&self) -> Arc<LineIndex> { + match self { + AssetOrDocument::Asset(a) => a.line_index(), + AssetOrDocument::Document(d) => d.line_index(), + } + } + + pub fn maybe_navigation_tree(&self) -> Option<Arc<tsc::NavigationTree>> { + match self { + AssetOrDocument::Asset(a) => a.maybe_navigation_tree(), + AssetOrDocument::Document(d) => d.maybe_navigation_tree(), + } + } + + pub fn get_maybe_dependency( + &self, + position: &lsp::Position, + ) -> Option<(String, deno_graph::Dependency, deno_graph::Range)> { + self + .document() + .map(|d| d.get_maybe_dependency(position)) + .flatten() + } + + pub fn maybe_parsed_source( + &self, + ) -> Option<Result<deno_ast::ParsedSource, deno_graph::ModuleGraphError>> { + self.document().map(|d| d.maybe_parsed_source()).flatten() + } + + pub fn document_version(&self) -> Option<i32> { + self.document().map(|d| d.maybe_lsp_version()).flatten() + } +} + // TODO(@kitsonk) expose the synthetic module from deno_graph #[derive(Debug)] struct SyntheticModule { @@ -186,9 +243,9 @@ impl SyntheticModule { } } } - -#[derive(Debug)] -pub(crate) struct Document { +#[derive(Debug, Clone)] +struct DocumentInner { + fs_version: String, line_index: Arc<LineIndex>, maybe_language_id: Option<LanguageId>, maybe_lsp_version: Option<i32>, @@ -196,15 +253,17 @@ pub(crate) struct Document { Option<Result<deno_graph::Module, deno_graph::ModuleGraphError>>, maybe_navigation_tree: Option<Arc<tsc::NavigationTree>>, maybe_warning: Option<String>, - source: SourceTextInfo, specifier: ModuleSpecifier, - version: String, + text_info: SourceTextInfo, } +#[derive(Debug, Clone)] +pub(crate) struct Document(Arc<DocumentInner>); + impl Document { fn new( specifier: ModuleSpecifier, - version: String, + fs_version: String, maybe_headers: Option<&HashMap<String, String>>, content: Arc<String>, maybe_resolver: Option<&dyn deno_graph::source::Resolver>, @@ -223,29 +282,64 @@ impl Document { maybe_resolver, Some(&parser), )); - let source = SourceTextInfo::new(content); - let line_index = Arc::new(LineIndex::new(source.text_str())); - Self { + let text_info = SourceTextInfo::new(content); + let line_index = Arc::new(LineIndex::new(text_info.text_str())); + Self(Arc::new(DocumentInner { + fs_version, line_index, maybe_language_id: None, maybe_lsp_version: None, maybe_module, maybe_navigation_tree: None, maybe_warning, - source, + text_info, specifier, - version, - } + })) } - fn change( - &mut self, + fn open( + specifier: ModuleSpecifier, + version: i32, + language_id: LanguageId, + content: Arc<String>, + maybe_resolver: Option<&dyn deno_graph::source::Resolver>, + ) -> Self { + let maybe_headers = language_id.as_headers(); + let parser = SourceParser::default(); + let maybe_module = if language_id.is_diagnosable() { + Some(deno_graph::parse_module( + &specifier, + maybe_headers, + content.clone(), + maybe_resolver, + Some(&parser), + )) + } else { + None + }; + let source = SourceTextInfo::new(content); + let line_index = Arc::new(LineIndex::new(source.text_str())); + Self(Arc::new(DocumentInner { + fs_version: "1".to_string(), + line_index, + maybe_language_id: Some(language_id), + maybe_lsp_version: Some(version), + maybe_module, + maybe_navigation_tree: None, + maybe_warning: None, + text_info: source, + specifier, + })) + } + + fn with_change( + &self, version: i32, changes: Vec<lsp::TextDocumentContentChangeEvent>, maybe_resolver: Option<&dyn deno_graph::source::Resolver>, - ) -> Result<(), AnyError> { - let mut content = self.source.text_str().to_string(); - let mut line_index = self.line_index.clone(); + ) -> Result<Document, AnyError> { + let mut content = self.0.text_info.text_str().to_string(); + let mut line_index = self.0.line_index.clone(); let mut index_valid = IndexValid::All; for change in changes { if let Some(range) = change.range { @@ -261,49 +355,91 @@ impl Document { } } let content = Arc::new(content); - if self + let maybe_module = if self + .0 .maybe_language_id .as_ref() .map(|li| li.is_diagnosable()) .unwrap_or(false) { let maybe_headers = self + .0 .maybe_language_id .as_ref() .map(|li| li.as_headers()) .flatten(); let parser = SourceParser::default(); - self.maybe_module = Some(deno_graph::parse_module( - &self.specifier, + Some(deno_graph::parse_module( + &self.0.specifier, maybe_headers, content.clone(), maybe_resolver, Some(&parser), - )); + )) } else { - self.maybe_module = None; - } - self.source = SourceTextInfo::new(content); - self.line_index = if index_valid == IndexValid::All { + None + }; + let source = SourceTextInfo::new(content); + let line_index = if index_valid == IndexValid::All { line_index } else { - Arc::new(LineIndex::new(self.source.text_str())) + Arc::new(LineIndex::new(source.text_str())) }; - self.maybe_lsp_version = Some(version); - self.maybe_navigation_tree = None; - Ok(()) + Ok(Document(Arc::new(DocumentInner { + text_info: source, + line_index, + maybe_module, + maybe_lsp_version: Some(version), + maybe_navigation_tree: None, + ..(*self.0).clone() + }))) + } + + fn with_closed(&self) -> Document { + Document(Arc::new(DocumentInner { + maybe_lsp_version: None, + maybe_language_id: None, + ..(*self.0).clone() + })) + } + + fn with_navigation_tree( + &self, + navigation_tree: Arc<tsc::NavigationTree>, + ) -> Document { + Document(Arc::new(DocumentInner { + maybe_navigation_tree: Some(navigation_tree), + ..(*self.0).clone() + })) } - fn close(&mut self) { - self.maybe_lsp_version = None; - self.maybe_language_id = None; + pub fn specifier(&self) -> &ModuleSpecifier { + &self.0.specifier } - fn content(&self) -> Arc<String> { - self.source.text() + pub fn content(&self) -> Arc<String> { + self.0.text_info.text() } - fn is_diagnosable(&self) -> bool { + pub fn text_info(&self) -> SourceTextInfo { + self.0.text_info.clone() + } + + pub fn line_index(&self) -> Arc<LineIndex> { + self.0.line_index.clone() + } + + fn fs_version(&self) -> &str { + self.0.fs_version.as_str() + } + + pub fn script_version(&self) -> String { + self + .maybe_lsp_version() + .map_or_else(|| self.fs_version().to_string(), |v| v.to_string()) + } + + pub fn is_diagnosable(&self) -> bool { matches!( self.media_type(), // todo(#12410): Update with new media types for TS 4.5 @@ -315,58 +451,82 @@ impl Document { ) } - fn is_open(&self) -> bool { - self.maybe_lsp_version.is_some() + pub fn is_open(&self) -> bool { + self.0.maybe_lsp_version.is_some() } - fn maybe_types_dependency(&self) -> deno_graph::Resolved { - let module_result = self.maybe_module.as_ref()?; + pub fn maybe_types_dependency(&self) -> deno_graph::Resolved { + let module_result = self.0.maybe_module.as_ref()?; let module = module_result.as_ref().ok()?; let (_, maybe_dep) = module.maybe_types_dependency.as_ref()?; maybe_dep.clone() } - fn media_type(&self) -> MediaType { - if let Some(Ok(module)) = &self.maybe_module { + pub fn media_type(&self) -> MediaType { + if let Some(Ok(module)) = &self.0.maybe_module { module.media_type } else { - MediaType::from(&self.specifier) + MediaType::from(&self.0.specifier) } } - fn open( - specifier: ModuleSpecifier, - version: i32, - language_id: LanguageId, - content: Arc<String>, - maybe_resolver: Option<&dyn deno_graph::source::Resolver>, - ) -> Self { - let maybe_headers = language_id.as_headers(); - let parser = SourceParser::default(); - let maybe_module = if language_id.is_diagnosable() { - Some(deno_graph::parse_module( - &specifier, - maybe_headers, - content.clone(), - maybe_resolver, - Some(&parser), - )) - } else { - None + /// Returns the current language server client version if any. + pub fn maybe_lsp_version(&self) -> Option<i32> { + self.0.maybe_lsp_version + } + + fn maybe_module( + &self, + ) -> Option<&Result<deno_graph::Module, deno_graph::ModuleGraphError>> { + self.0.maybe_module.as_ref() + } + + pub fn maybe_parsed_source( + &self, + ) -> Option<Result<deno_ast::ParsedSource, deno_graph::ModuleGraphError>> { + self.maybe_module().map(|r| { + r.as_ref() + .map(|m| m.parsed_source.clone()) + .map_err(|err| err.clone()) + }) + } + + pub fn maybe_navigation_tree(&self) -> Option<Arc<tsc::NavigationTree>> { + self.0.maybe_navigation_tree.clone() + } + + pub fn maybe_warning(&self) -> Option<String> { + self.0.maybe_warning.clone() + } + + pub fn dependencies(&self) -> Option<Vec<(String, deno_graph::Dependency)>> { + let module = self.maybe_module()?.as_ref().ok()?; + Some( + module + .dependencies + .iter() + .map(|(s, d)| (s.clone(), d.clone())) + .collect(), + ) + } + + /// If the supplied position is within a dependency range, return the resolved + /// string specifier for the dependency, the resolved dependency and the range + /// in the source document of the specifier. + pub fn get_maybe_dependency( + &self, + position: &lsp::Position, + ) -> Option<(String, deno_graph::Dependency, deno_graph::Range)> { + let module = self.maybe_module()?.as_ref().ok()?; + let position = deno_graph::Position { + line: position.line as usize, + character: position.character as usize, }; - let source = SourceTextInfo::new(content); - let line_index = Arc::new(LineIndex::new(source.text_str())); - Self { - line_index, - maybe_language_id: Some(language_id), - maybe_lsp_version: Some(version), - maybe_module, - maybe_navigation_tree: None, - maybe_warning: None, - source, - specifier, - version: "1".to_string(), - } + module.dependencies.iter().find_map(|(s, dep)| { + dep + .includes(&position) + .map(|r| (s.clone(), dep.clone(), r.clone())) + }) } } @@ -446,7 +606,7 @@ fn recurse_dependents( } #[derive(Debug, Default)] -struct Inner { +struct DocumentsInner { /// The DENO_DIR that the documents looks for non-file based modules. cache: HttpCache, /// A flag that indicates that stated data is potentially invalid and needs to @@ -468,7 +628,7 @@ struct Inner { redirects: HashMap<ModuleSpecifier, ModuleSpecifier>, } -impl Inner { +impl DocumentsInner { fn new(location: &Path) -> Self { Self { cache: HttpCache::new(location), @@ -484,7 +644,7 @@ impl Inner { /// Adds a document by reading the document from the file system. fn add(&mut self, specifier: ModuleSpecifier) -> Option<Document> { - let version = self.calculate_version(&specifier)?; + let fs_version = self.calculate_fs_version(&specifier)?; let path = self.get_path(&specifier)?; let bytes = fs::read(path).ok()?; let doc = if specifier.scheme() == "file" { @@ -493,7 +653,7 @@ impl Inner { let content = Arc::new(get_source_from_bytes(bytes, maybe_charset).ok()?); Document::new( specifier.clone(), - version, + fs_version, None, content, self.get_maybe_resolver(), @@ -507,7 +667,7 @@ impl Inner { let content = Arc::new(get_source_from_bytes(bytes, maybe_charset).ok()?); Document::new( specifier.clone(), - version, + fs_version, maybe_headers, content, self.get_maybe_resolver(), @@ -524,7 +684,7 @@ impl Inner { let mut dependents_map: HashMap<ModuleSpecifier, HashSet<ModuleSpecifier>> = HashMap::new(); for (specifier, doc) in &self.docs { - if let Some(Ok(module)) = &doc.maybe_module { + if let Some(Ok(module)) = doc.maybe_module() { for dependency in module.dependencies.values() { if let Some(dep) = dependency.get_code() { dependents_map @@ -550,7 +710,10 @@ impl Inner { self.dependents_map = dependents_map; } - fn calculate_version(&self, specifier: &ModuleSpecifier) -> Option<String> { + fn calculate_fs_version( + &self, + specifier: &ModuleSpecifier, + ) -> Option<String> { let path = self.get_path(specifier)?; let metadata = fs::metadata(path).ok()?; if let Ok(modified) = metadata.modified() { @@ -569,16 +732,8 @@ impl Inner { specifier: &ModuleSpecifier, version: i32, changes: Vec<lsp::TextDocumentContentChangeEvent>, - ) -> Result<(), AnyError> { - // this duplicates the .get_resolver() method, because there is no easy - // way to avoid the double borrow of self that occurs here with getting the - // mut doc out. - let maybe_resolver = if self.maybe_jsx_resolver.is_some() { - self.maybe_jsx_resolver.as_ref().map(|jr| jr.as_resolver()) - } else { - self.maybe_import_map.as_ref().map(|im| im.as_resolver()) - }; - let doc = self.docs.get_mut(specifier).map_or_else( + ) -> Result<Document, AnyError> { + let doc = self.docs.get(specifier).map_or_else( || { Err(custom_error( "NotFound", @@ -588,7 +743,9 @@ impl Inner { Ok, )?; self.dirty = true; - doc.change(version, changes, maybe_resolver) + let doc = doc.with_change(version, changes, self.get_maybe_resolver())?; + self.docs.insert(doc.specifier().clone(), doc.clone()); + Ok(doc) } fn close(&mut self, specifier: &ModuleSpecifier) -> Result<(), AnyError> { @@ -601,7 +758,7 @@ impl Inner { }, Ok, )?; - doc.close(); + *doc = doc.with_closed(); self.dirty = true; Ok(()) } @@ -634,25 +791,6 @@ impl Inner { self.docs.contains_key(&specifier) } - fn content(&mut self, specifier: &ModuleSpecifier) -> Option<Arc<String>> { - self.get(specifier).map(|d| d.content()) - } - - fn dependencies( - &mut self, - specifier: &ModuleSpecifier, - ) -> Option<Vec<(String, deno_graph::Dependency)>> { - let doc = self.get(specifier)?; - let module = doc.maybe_module.as_ref()?.as_ref().ok()?; - Some( - module - .dependencies - .iter() - .map(|(s, d)| (s.clone(), d.clone())) - .collect(), - ) - } - fn dependents( &mut self, specifier: &ModuleSpecifier, @@ -678,22 +816,13 @@ impl Inner { self.docs.get(&specifier) } - fn get_maybe_dependency( - &mut self, - specifier: &ModuleSpecifier, - position: &lsp::Position, - ) -> Option<(String, deno_graph::Dependency, deno_graph::Range)> { - let doc = self.get(specifier)?; - let module = doc.maybe_module.as_ref()?.as_ref().ok()?; - let position = deno_graph::Position { - line: position.line as usize, - character: position.character as usize, - }; - module.dependencies.iter().find_map(|(s, dep)| { - dep - .includes(&position) - .map(|r| (s.clone(), dep.clone(), r.clone())) - }) + fn get_cached(&mut self, specifier: &ModuleSpecifier) -> Option<&Document> { + let specifier = self + .resolve_specifier(specifier) + .unwrap_or_else(|| specifier.clone()); + // this does not use `self.get` since that lazily adds documents, and we + // only care about documents already in the cache. + self.docs.get(&specifier) } fn get_maybe_resolver(&self) -> Option<&dyn deno_graph::source::Resolver> { @@ -704,26 +833,6 @@ impl Inner { } } - fn get_maybe_types_for_dependency( - &mut self, - dependency: &deno_graph::Dependency, - ) -> deno_graph::Resolved { - let code_dep = dependency.maybe_code.as_ref()?; - let (specifier, _) = code_dep.as_ref().ok()?; - let doc = self.get(specifier)?; - doc.maybe_types_dependency() - } - - fn get_navigation_tree( - &mut self, - specifier: &ModuleSpecifier, - ) -> Option<Arc<tsc::NavigationTree>> { - self - .get(specifier) - .map(|d| d.maybe_navigation_tree.clone()) - .flatten() - } - fn get_path(&self, specifier: &ModuleSpecifier) -> Option<PathBuf> { if specifier.scheme() == "file" { specifier.to_file_path().ok() @@ -737,38 +846,19 @@ impl Inner { } } - fn is_diagnosable(&mut self, specifier: &ModuleSpecifier) -> bool { - if let Some(doc) = self.get(specifier) { - doc.is_diagnosable() - } else { - false - } - } - - fn is_formattable(&mut self, specifier: &ModuleSpecifier) -> bool { - // currently any document that is open in the language server is formattable - self.is_open(specifier) - } - - fn is_open(&mut self, specifier: &ModuleSpecifier) -> bool { - let specifier = self - .resolve_specifier(specifier) - .unwrap_or_else(|| specifier.clone()); - // this does not use `self.get` since that lazily adds documents, and we - // only care about documents already in the cache. - if let Some(doc) = self.docs.get(&specifier) { - doc.is_open() - } else { - false - } - } - fn is_valid(&mut self, specifier: &ModuleSpecifier) -> bool { - if self.is_open(specifier) { + if self + .get_cached(specifier) + .map(|d| d.is_open()) + .unwrap_or(false) + { true } else if let Some(specifier) = self.resolve_specifier(specifier) { - self.docs.get(&specifier).map(|d| d.version.clone()) - == self.calculate_version(&specifier) + self + .docs + .get(&specifier) + .map(|d| d.fs_version().to_string()) + == self.calculate_fs_version(&specifier) } else { // even though it isn't valid, it just can't exist, so we will say it is // valid @@ -776,62 +866,44 @@ impl Inner { } } - fn line_index( - &mut self, - specifier: &ModuleSpecifier, - ) -> Option<Arc<LineIndex>> { - let specifier = self.resolve_specifier(specifier)?; - self.docs.get(&specifier).map(|doc| doc.line_index.clone()) - } - - fn lsp_version(&self, specifier: &ModuleSpecifier) -> Option<i32> { - self - .docs - .get(specifier) - .map(|doc| doc.maybe_lsp_version) - .flatten() - } - - fn maybe_warning(&mut self, specifier: &ModuleSpecifier) -> Option<String> { - self - .get(specifier) - .map(|d| d.maybe_warning.clone()) - .flatten() - } - fn open( &mut self, specifier: ModuleSpecifier, version: i32, language_id: LanguageId, content: Arc<String>, - ) { + ) -> Document { let maybe_resolver = self.get_maybe_resolver(); - let document_data = Document::open( + let document = Document::open( specifier.clone(), version, language_id, content, maybe_resolver, ); - self.docs.insert(specifier, document_data); + self.docs.insert(specifier, document.clone()); self.dirty = true; + document } - fn parsed_source( - &mut self, - specifier: &ModuleSpecifier, - ) -> Option<Result<deno_ast::ParsedSource, deno_graph::ModuleGraphError>> { + fn documents( + &self, + open_only: bool, + diagnosable_only: bool, + ) -> Vec<Document> { self - .get(specifier) - .map(|doc| { - doc.maybe_module.as_ref().map(|r| { - r.as_ref() - .map(|m| m.parsed_source.clone()) - .map_err(|err| err.clone()) - }) + .docs + .values() + .filter_map(|doc| { + let open = open_only && doc.is_open(); + let diagnosable = diagnosable_only && doc.is_diagnosable(); + if (!open_only || open) && (!diagnosable_only || diagnosable) { + Some(doc.clone()) + } else { + None + } }) - .flatten() + .collect() } fn resolve( @@ -841,7 +913,7 @@ impl Inner { ) -> Option<Vec<Option<(ModuleSpecifier, MediaType)>>> { let doc = self.get(referrer)?; let mut results = Vec::new(); - if let Some(Ok(module)) = &doc.maybe_module { + if let Some(Ok(module)) = doc.maybe_module() { let dependencies = module.dependencies.clone(); for specifier in specifiers { if specifier.starts_with("asset:") { @@ -878,8 +950,7 @@ impl Inner { specifier: &ModuleSpecifier, ) -> Option<(ModuleSpecifier, MediaType)> { let doc = self.get(specifier)?; - let maybe_module = - doc.maybe_module.as_ref().map(|r| r.as_ref().ok()).flatten(); + let maybe_module = doc.maybe_module().map(|r| r.as_ref().ok()).flatten(); let maybe_types_dependency = maybe_module .map(|m| { m.maybe_types_dependency @@ -969,37 +1040,10 @@ impl Inner { let doc = self.docs.get_mut(specifier).ok_or_else(|| { custom_error("NotFound", format!("Specifier not found {}", specifier)) })?; - doc.maybe_navigation_tree = Some(navigation_tree); + *doc = doc.with_navigation_tree(navigation_tree); Ok(()) } - fn specifiers( - &self, - open_only: bool, - diagnosable_only: bool, - ) -> Vec<ModuleSpecifier> { - self - .docs - .iter() - .filter_map(|(specifier, doc)| { - let open = open_only && doc.is_open(); - let diagnosable = diagnosable_only && doc.is_diagnosable(); - if (!open_only || open) && (!diagnosable_only || diagnosable) { - Some(specifier.clone()) - } else { - None - } - }) - .collect() - } - - fn text_info( - &mut self, - specifier: &ModuleSpecifier, - ) -> Option<SourceTextInfo> { - self.get(specifier).map(|d| d.source.clone()) - } - fn update_config( &mut self, maybe_import_map: Option<Arc<import_map::ImportMap>>, @@ -1029,21 +1073,28 @@ impl Inner { } self.dirty = true; } - - fn version(&mut self, specifier: &ModuleSpecifier) -> Option<String> { - self.get(specifier).map(|d| { - d.maybe_lsp_version - .map_or_else(|| d.version.clone(), |v| v.to_string()) - }) - } } #[derive(Debug, Clone, Default)] -pub(crate) struct Documents(Arc<Mutex<Inner>>); +pub(crate) struct Documents(Arc<Mutex<DocumentsInner>>); impl Documents { pub fn new(location: &Path) -> Self { - Self(Arc::new(Mutex::new(Inner::new(location)))) + Self(Arc::new(Mutex::new(DocumentsInner::new(location)))) + } + + /// "Open" a document from the perspective of the editor, meaning that + /// requests for information from the document will come from the in-memory + /// representation received from the language server client, versus reading + /// information from the disk. + pub fn open( + &self, + specifier: ModuleSpecifier, + version: i32, + language_id: LanguageId, + content: Arc<String>, + ) -> Document { + self.0.lock().open(specifier, version, language_id, content) } /// Apply language server content changes to an open document. @@ -1052,7 +1103,7 @@ impl Documents { specifier: &ModuleSpecifier, version: i32, changes: Vec<lsp::TextDocumentContentChangeEvent>, - ) -> Result<(), AnyError> { + ) -> Result<Document, AnyError> { self.0.lock().change(specifier, version, changes) } @@ -1078,20 +1129,6 @@ impl Documents { self.0.lock().contains_specifier(specifier) } - /// If the specifier can be resolved to a document, return its current - /// content, otherwise none. - pub fn content(&self, specifier: &ModuleSpecifier) -> Option<Arc<String>> { - self.0.lock().content(specifier) - } - - /// Return an optional vector of dependencies for a given specifier. - pub fn dependencies( - &self, - specifier: &ModuleSpecifier, - ) -> Option<Vec<(String, deno_graph::Dependency)>> { - self.0.lock().dependencies(specifier) - } - /// Return an array of specifiers, if any, that are dependent upon the /// supplied specifier. This is used to determine invalidation of diagnostics /// when a module has been changed. @@ -1102,85 +1139,21 @@ impl Documents { self.0.lock().dependents(specifier) } - /// If the supplied position is within a dependency range, return the resolved - /// string specifier for the dependency, the resolved dependency and the range - /// in the source document of the specifier. - pub fn get_maybe_dependency( - &self, - specifier: &ModuleSpecifier, - position: &lsp::Position, - ) -> Option<(String, deno_graph::Dependency, deno_graph::Range)> { - self.0.lock().get_maybe_dependency(specifier, position) - } - - /// For a given dependency, try to resolve the maybe_types_dependency for the - /// dependency. This covers modules that assert their own types, like via the - /// triple-slash reference, or the `X-TypeScript-Types` header. - pub fn get_maybe_types_for_dependency( - &self, - dependency: &deno_graph::Dependency, - ) -> deno_graph::Resolved { - self.0.lock().get_maybe_types_for_dependency(dependency) - } - - /// Get a reference to the navigation tree stored for a given specifier, if - /// any. - pub fn get_navigation_tree( - &self, - specifier: &ModuleSpecifier, - ) -> Option<Arc<tsc::NavigationTree>> { - self.0.lock().get_navigation_tree(specifier) - } - - /// Indicates that a specifier is able to be diagnosed by the language server - pub fn is_diagnosable(&self, specifier: &ModuleSpecifier) -> bool { - self.0.lock().is_diagnosable(specifier) - } - - /// Indicates that a specifier is formattable. - pub fn is_formattable(&self, specifier: &ModuleSpecifier) -> bool { - self.0.lock().is_formattable(specifier) - } - - /// Return a reference to the line index for a given specifiers, if any. - pub fn line_index( - &self, - specifier: &ModuleSpecifier, - ) -> Option<Arc<LineIndex>> { - self.0.lock().line_index(specifier) - } - - /// Return the current language server client version for a given specifier, - /// if any. - pub fn lsp_version(&self, specifier: &ModuleSpecifier) -> Option<i32> { - self.0.lock().lsp_version(specifier) - } - - /// Return a warning header for a given specifier, if present. - pub fn maybe_warning(&self, specifier: &ModuleSpecifier) -> Option<String> { - self.0.lock().maybe_warning(specifier) - } - - /// "Open" a document from the perspective of the editor, meaning that - /// requests for information from the document will come from the in-memory - /// representation received from the language server client, versus reading - /// information from the disk. - pub fn open( + /// Return a vector of documents that are contained in the document store, + /// where `open_only` flag would provide only those documents currently open + /// in the editor and `diagnosable_only` would provide only those documents + /// that the language server can provide diagnostics for. + pub fn documents( &self, - specifier: ModuleSpecifier, - version: i32, - language_id: LanguageId, - content: Arc<String>, - ) { - self.0.lock().open(specifier, version, language_id, content) + open_only: bool, + diagnosable_only: bool, + ) -> Vec<Document> { + self.0.lock().documents(open_only, diagnosable_only) } - /// Return the parsed source or the module graph error for a given specifier. - pub fn parsed_source( - &self, - specifier: &ModuleSpecifier, - ) -> Option<Result<deno_ast::ParsedSource, deno_graph::ModuleGraphError>> { - self.0.lock().parsed_source(specifier) + /// Return a document for the specifier. + pub fn get(&self, specifier: &ModuleSpecifier) -> Option<Document> { + self.0.lock().get(specifier).cloned() } /// For a given set of string specifiers, resolve each one from the graph, @@ -1211,26 +1184,6 @@ impl Documents { .set_navigation_tree(specifier, navigation_tree) } - /// Return a vector of specifiers that are contained in the document store, - /// where `open_only` flag would provide only those documents currently open - /// in the editor and `diagnosable_only` would provide only those documents - /// that the language server can provide diagnostics for. - pub fn specifiers( - &self, - open_only: bool, - diagnosable_only: bool, - ) -> Vec<ModuleSpecifier> { - self.0.lock().specifiers(open_only, diagnosable_only) - } - - /// Return the current text info for a given specifier. - pub fn text_info( - &self, - specifier: &ModuleSpecifier, - ) -> Option<SourceTextInfo> { - self.0.lock().text_info(specifier) - } - pub fn update_config( &self, maybe_import_map: Option<Arc<import_map::ImportMap>>, @@ -1241,11 +1194,6 @@ impl Documents { .lock() .update_config(maybe_import_map, maybe_config_file) } - - /// Return the version of a document in the document cache. - pub fn version(&self, specifier: &ModuleSpecifier) -> Option<String> { - self.0.lock().version(specifier) - } } #[cfg(test)] @@ -1270,15 +1218,10 @@ console.log(b); "# .to_string(), ); - documents.open( - specifier.clone(), - 1, - "javascript".parse().unwrap(), - content, - ); - assert!(documents.is_formattable(&specifier)); - assert!(documents.is_diagnosable(&specifier)); - assert!(documents.line_index(&specifier).is_some()); + let document = + documents.open(specifier, 1, "javascript".parse().unwrap(), content); + assert!(document.is_open()); + assert!(document.is_diagnosable()); } #[test] @@ -1318,7 +1261,7 @@ console.log(b); ) .unwrap(); assert_eq!( - documents.content(&specifier).unwrap().as_str(), + documents.get(&specifier).unwrap().content().as_str(), r#"import * as b from "./b.ts"; console.log(b, "hello deno"); "# |