summaryrefslogtreecommitdiff
path: root/cli/lsp/documents.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/lsp/documents.rs')
-rw-r--r--cli/lsp/documents.rs58
1 files changed, 30 insertions, 28 deletions
diff --git a/cli/lsp/documents.rs b/cli/lsp/documents.rs
index 936d225ec..308e987bd 100644
--- a/cli/lsp/documents.rs
+++ b/cli/lsp/documents.rs
@@ -244,16 +244,18 @@ type MaybeModuleResult =
type MaybeParsedSourceResult =
Option<Result<ParsedSource, deno_ast::Diagnostic>>;
-#[derive(Debug, Clone)]
+#[derive(Debug)]
struct DocumentInner {
- /// contains the last-known-good set of dependencies from parsing the module
+ /// Contains the last-known-good set of dependencies from parsing the module.
dependencies: Arc<DocumentDependencies>,
fs_version: String,
line_index: Arc<LineIndex>,
maybe_language_id: Option<LanguageId>,
maybe_lsp_version: Option<i32>,
maybe_module: MaybeModuleResult,
- maybe_navigation_tree: Option<Arc<tsc::NavigationTree>>,
+ // this is a lazily constructed value based on the state of the document,
+ // so having a mutex to hold it is ok
+ maybe_navigation_tree: Mutex<Option<Arc<tsc::NavigationTree>>>,
maybe_parsed_source: MaybeParsedSourceResult,
specifier: ModuleSpecifier,
text_info: SourceTextInfo,
@@ -291,7 +293,7 @@ impl Document {
maybe_language_id: None,
maybe_lsp_version: None,
maybe_module,
- maybe_navigation_tree: None,
+ maybe_navigation_tree: Mutex::new(None),
maybe_parsed_source,
text_info,
specifier,
@@ -327,7 +329,7 @@ impl Document {
maybe_language_id: Some(language_id),
maybe_lsp_version: Some(version),
maybe_module,
- maybe_navigation_tree: None,
+ maybe_navigation_tree: Mutex::new(None),
maybe_parsed_source,
text_info: source,
specifier,
@@ -390,27 +392,19 @@ impl Document {
Arc::new(LineIndex::new(text_info.text_str()))
};
Ok(Document(Arc::new(DocumentInner {
+ specifier: self.0.specifier.clone(),
+ fs_version: self.0.fs_version.clone(),
+ maybe_language_id: self.0.maybe_language_id.clone(),
dependencies,
text_info,
line_index,
maybe_module,
maybe_parsed_source,
maybe_lsp_version: Some(version),
- maybe_navigation_tree: None,
- ..(*self.0).clone()
+ maybe_navigation_tree: Mutex::new(None),
})))
}
- fn with_navigation_tree(
- &self,
- navigation_tree: Arc<tsc::NavigationTree>,
- ) -> Document {
- Document(Arc::new(DocumentInner {
- maybe_navigation_tree: Some(navigation_tree),
- ..(*self.0).clone()
- }))
- }
-
pub fn specifier(&self) -> &ModuleSpecifier {
&self.0.specifier
}
@@ -494,7 +488,21 @@ impl Document {
}
pub fn maybe_navigation_tree(&self) -> Option<Arc<tsc::NavigationTree>> {
- self.0.maybe_navigation_tree.clone()
+ self.0.maybe_navigation_tree.lock().clone()
+ }
+
+ pub fn update_navigation_tree_if_version(
+ &self,
+ tree: Arc<tsc::NavigationTree>,
+ script_version: &str,
+ ) {
+ // Ensure we are updating the same document that the navigation tree was
+ // created for. Note: this should not be racy between the version check
+ // and setting the navigation tree, because the document is immutable
+ // and this is enforced by it being wrapped in an Arc.
+ if self.script_version() == script_version {
+ *self.0.maybe_navigation_tree.lock() = Some(tree);
+ }
}
pub fn dependencies(&self) -> &BTreeMap<String, deno_graph::Dependency> {
@@ -1018,23 +1026,17 @@ impl Documents {
/// Tries to cache a navigation tree that is associated with the provided specifier
/// if the document stored has the same script version.
pub fn try_cache_navigation_tree(
- &mut self,
+ &self,
specifier: &ModuleSpecifier,
script_version: &str,
navigation_tree: Arc<tsc::NavigationTree>,
) -> Result<(), AnyError> {
- if let Some(doc) = self.open_docs.get_mut(specifier) {
- if doc.script_version() == script_version {
- *doc = doc.with_navigation_tree(navigation_tree);
- }
+ if let Some(doc) = self.open_docs.get(specifier) {
+ doc.update_navigation_tree_if_version(navigation_tree, script_version)
} else {
let mut file_system_docs = self.file_system_docs.lock();
if let Some(doc) = file_system_docs.docs.get_mut(specifier) {
- // ensure we are updating the same document
- // that the navigation tree was created for
- if doc.script_version() == script_version {
- *doc = doc.with_navigation_tree(navigation_tree);
- }
+ doc.update_navigation_tree_if_version(navigation_tree, script_version);
} else {
return Err(custom_error(
"NotFound",