Skip to content

Commit

Permalink
perf(lsp): fix redundant file reads (denoland#20802)
Browse files Browse the repository at this point in the history
  • Loading branch information
nayeemrmn committed Oct 12, 2023
1 parent cee2211 commit eaeb10c
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 20 deletions.
55 changes: 41 additions & 14 deletions cli/lsp/documents.rs
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,7 @@ impl Document {
version: i32,
language_id: LanguageId,
content: Arc<str>,
cache: &Arc<dyn HttpCache>,
resolver: &dyn deno_graph::source::Resolver,
) -> Self {
let maybe_headers = language_id.as_headers();
Expand All @@ -441,7 +442,8 @@ impl Document {
let line_index = Arc::new(LineIndex::new(text_info.text_str()));
Self(Arc::new(DocumentInner {
dependencies,
fs_version: "1".to_string(),
fs_version: calculate_fs_version(cache, &specifier)
.unwrap_or_else(|| "1".to_string()),
line_index,
maybe_language_id: Some(language_id),
maybe_lsp_version: Some(version),
Expand Down Expand Up @@ -523,6 +525,23 @@ impl Document {
})))
}

pub fn saved(&self, cache: &Arc<dyn HttpCache>) -> Document {
Document(Arc::new(DocumentInner {
specifier: self.0.specifier.clone(),
fs_version: calculate_fs_version(cache, &self.0.specifier)
.unwrap_or_else(|| "1".to_string()),
maybe_language_id: self.0.maybe_language_id,
dependencies: self.0.dependencies.clone(),
text_info: self.0.text_info.clone(),
line_index: self.0.line_index.clone(),
maybe_headers: self.0.maybe_headers.clone(),
maybe_module: self.0.maybe_module.clone(),
maybe_parsed_source: self.0.maybe_parsed_source.clone(),
maybe_lsp_version: self.0.maybe_lsp_version,
maybe_navigation_tree: Mutex::new(None),
}))
}

pub fn specifier(&self) -> &ModuleSpecifier {
&self.0.specifier
}
Expand Down Expand Up @@ -953,6 +972,7 @@ impl Documents {
version,
language_id,
content,
&self.cache,
resolver,
);
let mut file_system_docs = self.file_system_docs.lock();
Expand Down Expand Up @@ -991,24 +1011,28 @@ impl Documents {
Ok(doc)
}

pub fn save(&mut self, specifier: &ModuleSpecifier) {
let doc = self.open_docs.get(specifier).cloned().or_else(|| {
let mut file_system_docs = self.file_system_docs.lock();
file_system_docs.docs.remove(specifier)
});
let Some(doc) = doc else {
return;
};
self.dirty = true;
let doc = doc.saved(&self.cache);
self.open_docs.insert(doc.specifier().clone(), doc.clone());
}

/// Close an open document, this essentially clears any editor state that is
/// being held, and the document store will revert to the file system if
/// information about the document is required.
pub fn close(&mut self, specifier: &ModuleSpecifier) -> Result<(), AnyError> {
if self.open_docs.remove(specifier).is_some() {
self.dirty = true;
} else {
if let Some(document) = self.open_docs.remove(specifier) {
let mut file_system_docs = self.file_system_docs.lock();
if file_system_docs.docs.remove(specifier).is_some() {
file_system_docs.dirty = true;
} else {
return Err(custom_error(
"NotFound",
format!("The specifier \"{specifier}\" was not found."),
));
}
file_system_docs.docs.insert(specifier.clone(), document);
self.dirty = true;
}

Ok(())
}

Expand Down Expand Up @@ -1496,7 +1520,10 @@ impl Documents {

let resolver = self.get_resolver();
while let Some(specifier) = doc_analyzer.pending_specifiers.pop_front() {
if let Some(doc) = file_system_docs.get(&self.cache, resolver, &specifier)
if let Some(doc) = self.open_docs.get(&specifier) {
doc_analyzer.analyze_doc(&specifier, doc);
} else if let Some(doc) =
file_system_docs.get(&self.cache, resolver, &specifier)
{
doc_analyzer.analyze_doc(&specifier, &doc);
}
Expand Down
12 changes: 6 additions & 6 deletions cli/lsp/language_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1373,18 +1373,17 @@ impl Inner {
let specifier = self
.url_map
.normalize_url(&params.text_document.uri, LspUrlKind::File);

if let Err(err) = self.documents.close(&specifier) {
error!("{}", err);
}
if self.is_diagnosable(&specifier) {
self.refresh_npm_specifiers().await;
let mut specifiers = self.documents.dependents(&specifier);
specifiers.push(specifier);
specifiers.push(specifier.clone());
self.diagnostics_server.invalidate(&specifiers);
self.send_diagnostics_update();
self.send_testing_update();
}
if let Err(err) = self.documents.close(&specifier) {
error!("{}", err);
}
self.performance.measure(mark);
}

Expand Down Expand Up @@ -3214,8 +3213,9 @@ impl tower_lsp::LanguageServer for LanguageServer {
async fn did_save(&self, params: DidSaveTextDocumentParams) {
let uri = &params.text_document.uri;
{
let inner = self.0.read().await;
let mut inner = self.0.write().await;
let specifier = inner.url_map.normalize_url(uri, LspUrlKind::File);
inner.documents.save(&specifier);
if !inner.config.workspace_settings().cache_on_save
|| !inner.config.specifier_enabled(&specifier)
|| !inner.diagnostics_state.has_no_cache_diagnostics(&specifier)
Expand Down

0 comments on commit eaeb10c

Please sign in to comment.