refactor(lsp): pass module parameters to tsc requests (#29674)

This commit is contained in:
Nayeem Rahman 2025-06-10 02:31:14 +01:00 committed by GitHub
parent ccc30edcb5
commit cb9245c69a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 518 additions and 639 deletions

View file

@ -1090,13 +1090,7 @@ async fn generate_ts_diagnostics(
let mut enabled_modules_with_diagnostics = Vec::new();
for ((scope, notebook_uri), enabled_modules) in enabled_modules_by_scope {
let (diagnostics_list, ambient_modules) = ts_server
.get_diagnostics(
snapshot.clone(),
enabled_modules.iter().map(|m| m.specifier.as_ref()),
scope.as_ref(),
notebook_uri.as_ref(),
&token,
)
.get_diagnostics(snapshot.clone(), &enabled_modules, &token)
.await?;
enabled_modules_with_diagnostics
.extend(enabled_modules.into_iter().zip(diagnostics_list));

View file

@ -1354,6 +1354,7 @@ impl DocumentModules {
/// This will not store any module entries, only retrieve existing entries or
/// create temporary entries for scopes where one doesn't exist.
// TODO(nayeemrmn): Support notebook scopes here.
pub fn inspect_or_temp_modules_by_scope(
&self,
document: &Document,

View file

@ -659,13 +659,7 @@ impl Inner {
.get_or_try_init(|| async {
self
.ts_server
.get_navigation_tree(
self.snapshot(),
&module.specifier,
module.scope.as_ref(),
module.notebook_uri.as_ref(),
token,
)
.get_navigation_tree(self.snapshot(), module, token)
.await
.map(Arc::new)
.map_err(|err| {
@ -1218,7 +1212,7 @@ impl Inner {
// a @types/node package and now's a good time to do that anyway
self.refresh_dep_info().await;
self.project_changed([], ProjectScopesChange::Config);
self.project_changed(vec![], ProjectScopesChange::Config);
}
#[cfg_attr(feature = "lsp-tracing", tracing::instrument(skip_all))]
@ -1260,14 +1254,11 @@ impl Inner {
if document.is_diagnosable() {
self.check_semantic_tokens_capabilities();
self.refresh_dep_info().await;
self.diagnostics_server.invalidate(&[document.uri.as_ref()]);
self.project_changed(
self
.document_modules
.primary_specifier(&Document::Open(document.clone()))
.map(|s| (s, ChangeKind::Opened)),
vec![(Document::Open(document), ChangeKind::Opened)],
ProjectScopesChange::None,
);
self.diagnostics_server.invalidate(&[document.uri.as_ref()]);
self.send_diagnostics_update();
self.send_testing_update();
}
@ -1310,18 +1301,15 @@ impl Inner {
{
config_changed = true;
}
self.diagnostics_server.invalidate(&[&document.uri]);
self.project_changed(
self
.document_modules
.primary_specifier(&Document::Open(document.clone()))
.map(|s| (s, ChangeKind::Modified)),
vec![(Document::Open(document), ChangeKind::Modified)],
if config_changed {
ProjectScopesChange::Config
} else {
ProjectScopesChange::None
},
);
self.diagnostics_server.invalidate(&[&document.uri]);
self.send_diagnostics_update();
self.send_testing_update();
}
@ -1416,14 +1404,10 @@ impl Inner {
if document.is_diagnosable() {
self.refresh_dep_info().await;
self.diagnostics_server.invalidate(&[&document.uri]);
let changed_specifier = self
.document_modules
.primary_specifier(&Document::Open(document.clone()))
.map(|s| (s, ChangeKind::Closed));
// Invalidate the weak references of `document` before calling
// `self.project_changed()` so its module entries will be dropped.
drop(document);
self.project_changed(changed_specifier, ProjectScopesChange::None);
self.project_changed(
vec![(Document::Open(document), ChangeKind::Closed)],
ProjectScopesChange::None,
);
self.send_diagnostics_update();
self.send_testing_update();
}
@ -1437,30 +1421,25 @@ impl Inner {
params.cell_text_documents,
);
let diagnosable_documents = documents
.iter()
.into_iter()
.filter(|d| d.is_diagnosable())
.collect::<Vec<_>>();
if !diagnosable_documents.is_empty() {
self.check_semantic_tokens_capabilities();
self.refresh_dep_info().await;
self.project_changed(
diagnosable_documents
.iter()
.flat_map(|d| {
let specifier = self
.document_modules
.primary_specifier(&Document::Open((*d).clone()))?;
Some((specifier, ChangeKind::Opened))
})
.collect::<Vec<_>>(),
ProjectScopesChange::OpenNotebooks,
);
self.diagnostics_server.invalidate(
&diagnosable_documents
.iter()
.map(|d| d.uri.as_ref())
.collect::<Vec<_>>(),
);
self.project_changed(
diagnosable_documents
.into_iter()
.map(|d| (Document::Open(d), ChangeKind::Opened))
.collect(),
ProjectScopesChange::OpenNotebooks,
);
self.send_diagnostics_update();
}
}
@ -1479,7 +1458,7 @@ impl Inner {
cells.text_content,
);
let diagnosable_documents = documents
.iter()
.into_iter()
.filter(|(d, _)| d.is_diagnosable())
.collect::<Vec<_>>();
if !diagnosable_documents.is_empty() {
@ -1494,28 +1473,23 @@ impl Inner {
{
config_changed = true;
}
self.project_changed(
diagnosable_documents
.iter()
.flat_map(|(d, k)| {
let specifier = self
.document_modules
.primary_specifier(&Document::Open(d.clone()))?;
Some((specifier, *k))
})
.collect::<Vec<_>>(),
if config_changed {
ProjectScopesChange::Config
} else {
ProjectScopesChange::None
},
);
self.diagnostics_server.invalidate(
&diagnosable_documents
.iter()
.map(|(d, _)| d.uri.as_ref())
.collect::<Vec<_>>(),
);
self.project_changed(
diagnosable_documents
.into_iter()
.map(|(d, k)| (Document::Open(d), k))
.collect(),
if config_changed {
ProjectScopesChange::Config
} else {
ProjectScopesChange::None
},
);
self.send_diagnostics_update();
}
}
@ -1554,7 +1528,7 @@ impl Inner {
.document_modules
.close_notebook_document(&params.notebook_document.uri);
let diagnosable_documents = documents
.iter()
.into_iter()
.filter(|d| d.is_diagnosable())
.collect::<Vec<_>>();
if !diagnosable_documents.is_empty() {
@ -1565,20 +1539,11 @@ impl Inner {
.map(|d| d.uri.as_ref())
.collect::<Vec<_>>(),
);
let changed_specifiers = diagnosable_documents
.iter()
.flat_map(|d| {
let specifier = self
.document_modules
.primary_specifier(&Document::Open((*d).clone()))?;
Some((specifier, ChangeKind::Closed))
})
.collect::<Vec<_>>();
// Invalidate the weak references of `documents` before calling
// `self.project_changed()` so their module entries will be dropped.
drop(documents);
self.project_changed(
changed_specifiers,
diagnosable_documents
.into_iter()
.map(|d| (Document::Open(d), ChangeKind::Closed))
.collect(),
ProjectScopesChange::OpenNotebooks,
);
self.send_diagnostics_update();
@ -1673,23 +1638,18 @@ impl Inner {
self.update_cache();
self.refresh_resolver().await;
self.refresh_documents_config().await;
self.diagnostics_server.invalidate_all();
self.project_changed(
changes
.iter()
.filter_map(|(_, e)| {
let document = self.document_modules.documents.inspect(&e.uri)?;
if !document.is_diagnosable() {
return None;
}
let specifier =
self.document_modules.primary_specifier(&document)?;
Some((specifier, ChangeKind::Modified))
Some((document, ChangeKind::Modified))
})
.collect::<Vec<_>>(),
ProjectScopesChange::None,
);
self.ts_server.cleanup_semantic_cache(self.snapshot()).await;
self.diagnostics_server.invalidate_all();
self.send_diagnostics_update();
self.send_testing_update();
deno_config_changes.extend(changes.iter().filter_map(|(s, e)| {
@ -1956,14 +1916,7 @@ impl Inner {
.offset_tsc(params.text_document_position_params.position)?;
let maybe_quick_info = self
.ts_server
.get_quick_info(
self.snapshot(),
&module.specifier,
position,
module.scope.as_ref(),
module.notebook_uri.as_ref(),
token,
)
.get_quick_info(self.snapshot(), &module, position, token)
.await
.map_err(|err| {
if token.is_cancelled() {
@ -2092,22 +2045,10 @@ impl Inner {
.ts_server
.get_code_fixes(
self.snapshot(),
&module.specifier,
&module,
module.line_index.offset_tsc(diagnostic.range.start)?
..module.line_index.offset_tsc(diagnostic.range.end)?,
codes,
(&self
.config
.tree
.fmt_config_for_specifier(&module.specifier)
.options)
.into(),
tsc::UserPreferences::from_config_for_specifier(
&self.config,
&module.specifier,
),
module.scope.as_ref(),
module.notebook_uri.as_ref(),
token,
)
.await
@ -2210,17 +2151,11 @@ impl Inner {
.ts_server
.get_applicable_refactors(
self.snapshot(),
&module.specifier,
&module,
module.line_index.offset_tsc(params.range.start)?
..module.line_index.offset_tsc(params.range.end)?,
Some(tsc::UserPreferences::from_config_for_specifier(
&self.config,
&module.specifier,
)),
params.context.trigger_kind,
only,
module.scope.as_ref(),
module.notebook_uri.as_ref(),
token,
)
.await
@ -2308,20 +2243,8 @@ impl Inner {
.ts_server
.get_combined_code_fix(
self.snapshot(),
&module.specifier,
&module,
&code_action_data.fix_id,
(&self
.config
.tree
.fmt_config_for_specifier(&module.specifier)
.options)
.into(),
tsc::UserPreferences::from_config_for_specifier(
&self.config,
&module.specifier,
),
module.scope.as_ref(),
module.notebook_uri.as_ref(),
token,
)
.await
@ -2389,23 +2312,11 @@ impl Inner {
.ts_server
.get_edits_for_refactor(
self.snapshot(),
&module.specifier,
(&self
.config
.tree
.fmt_config_for_specifier(&module.specifier)
.options)
.into(),
&module,
module.line_index.offset_tsc(action_data.range.start)?
..module.line_index.offset_tsc(action_data.range.end)?,
action_data.refactor_name.clone(),
action_data.action_name.clone(),
Some(tsc::UserPreferences::from_config_for_specifier(
&self.config,
&module.specifier,
)),
module.scope.as_ref(),
module.notebook_uri.as_ref(),
token,
)
.await
@ -2612,13 +2523,11 @@ impl Inner {
.ts_server
.get_document_highlights(
self.snapshot(),
&module.specifier,
&module,
module
.line_index
.offset_tsc(params.text_document_position_params.position)?,
vec![module.specifier.as_ref().clone()],
module.scope.as_ref(),
module.notebook_uri.as_ref(),
token,
)
.await
@ -2674,9 +2583,10 @@ impl Inner {
return Ok(None);
};
let mut locations = IndexSet::new();
for (scope, module) in self
for module in self
.document_modules
.inspect_or_temp_modules_by_scope(&document)
.into_values()
{
if token.is_cancelled() {
return Err(LspError::request_cancelled());
@ -2685,13 +2595,10 @@ impl Inner {
.ts_server
.find_references(
self.snapshot(),
&module.specifier,
&module,
module
.line_index
.offset_tsc(params.text_document_position.position)?,
scope.as_ref(),
// TODO(nayeemrmn): Support notebook scopes here.
None,
token,
)
.await
@ -2753,12 +2660,10 @@ impl Inner {
.ts_server
.get_definition(
self.snapshot(),
&module.specifier,
&module,
module
.line_index
.offset_tsc(params.text_document_position_params.position)?,
module.scope.as_ref(),
module.notebook_uri.as_ref(),
token,
)
.await
@ -2816,12 +2721,10 @@ impl Inner {
.ts_server
.get_type_definition(
self.snapshot(),
&module.specifier,
&module,
module
.line_index
.offset_tsc(params.text_document_position_params.position)?,
module.scope.as_ref(),
module.notebook_uri.as_ref(),
token,
)
.await
@ -2912,15 +2815,6 @@ impl Inner {
.await;
}
if response.is_none() {
let (trigger_character, trigger_kind) =
if let Some(context) = &params.context {
(
context.trigger_character.clone(),
Some(context.trigger_kind.into()),
)
} else {
(None, None)
};
let position = module
.line_index
.offset_tsc(params.text_document_position.position)?;
@ -2928,24 +2822,13 @@ impl Inner {
.ts_server
.get_completions(
self.snapshot(),
&module.specifier,
&module,
position,
tsc::GetCompletionsAtPositionOptions {
user_preferences: tsc::UserPreferences::from_config_for_specifier(
&self.config,
&module.specifier,
),
trigger_character,
trigger_kind,
},
(&self
.config
.tree
.fmt_config_for_specifier(&module.specifier)
.options)
.into(),
module.scope.as_ref(),
module.notebook_uri.as_ref(),
params
.context
.as_ref()
.and_then(|c| c.trigger_character.clone()),
params.context.as_ref().map(|c| c.trigger_kind.into()),
token,
)
.await
@ -3021,25 +2904,11 @@ impl Inner {
.ts_server
.get_completion_details(
self.snapshot(),
&module.specifier,
&module,
data.position,
data.name.clone(),
Some(
(&self
.config
.tree
.fmt_config_for_specifier(&module.specifier)
.options)
.into(),
),
data.source.clone(),
Some(tsc::UserPreferences::from_config_for_specifier(
&self.config,
&module.specifier,
)),
data.data.clone(),
module.scope.as_ref(),
module.notebook_uri.as_ref(),
token,
)
.await;
@ -3107,9 +2976,10 @@ impl Inner {
return Ok(None);
};
let mut implementations_with_modules = IndexMap::new();
for (scope, module) in self
for module in self
.document_modules
.inspect_or_temp_modules_by_scope(&document)
.into_values()
{
if token.is_cancelled() {
return Err(LspError::request_cancelled());
@ -3118,12 +2988,10 @@ impl Inner {
.ts_server
.get_implementations(
self.snapshot(),
&module.specifier,
&module,
module
.line_index
.offset_tsc(params.text_document_position_params.position)?,
scope.as_ref(),
module.notebook_uri.as_ref(),
token,
)
.await
@ -3186,13 +3054,7 @@ impl Inner {
};
let outlining_spans = self
.ts_server
.get_outlining_spans(
self.snapshot(),
&module.specifier,
module.scope.as_ref(),
module.notebook_uri.as_ref(),
token,
)
.get_outlining_spans(self.snapshot(), &module, token)
.await
.map_err(|err| {
if token.is_cancelled() {
@ -3244,9 +3106,10 @@ impl Inner {
return Ok(None);
};
let mut incoming_calls_with_modules = IndexMap::new();
for (scope, module) in self
for module in self
.document_modules
.inspect_or_temp_modules_by_scope(&document)
.into_values()
{
if token.is_cancelled() {
return Err(LspError::request_cancelled());
@ -3255,12 +3118,10 @@ impl Inner {
.ts_server
.provide_call_hierarchy_incoming_calls(
self.snapshot(),
&module.specifier,
&module,
module
.line_index
.offset_tsc(params.item.selection_range.start)?,
scope.as_ref(),
module.notebook_uri.as_ref(),
token,
)
.await
@ -3323,12 +3184,10 @@ impl Inner {
.ts_server
.provide_call_hierarchy_outgoing_calls(
self.snapshot(),
&module.specifier,
&module,
module
.line_index
.offset_tsc(params.item.selection_range.start)?,
module.scope.as_ref(),
module.notebook_uri.as_ref(),
token,
)
.await
@ -3386,12 +3245,10 @@ impl Inner {
.ts_server
.prepare_call_hierarchy(
self.snapshot(),
&module.specifier,
&module,
module
.line_index
.offset_tsc(params.text_document_position_params.position)?,
module.scope.as_ref(),
module.notebook_uri.as_ref(),
token,
)
.await
@ -3471,17 +3328,10 @@ impl Inner {
.ts_server
.find_rename_locations(
self.snapshot(),
&module.specifier,
&module,
module
.line_index
.offset_tsc(params.text_document_position.position)?,
tsc::UserPreferences::from_config_for_specifier(
&self.config,
&module.specifier,
),
scope.as_ref(),
// TODO(nayeemrmn): Support notebook scopes here.
None,
token,
)
.await
@ -3555,10 +3405,8 @@ impl Inner {
.ts_server
.get_smart_selection_range(
self.snapshot(),
&module.specifier,
&module,
module.line_index.offset_tsc(position)?,
module.scope.as_ref(),
module.notebook_uri.as_ref(),
token,
)
.await
@ -3609,10 +3457,8 @@ impl Inner {
.ts_server
.get_encoded_semantic_classifications(
self.snapshot(),
&module.specifier,
&module,
0..module.line_index.text_content_length_utf16().into(),
module.scope.as_ref(),
module.notebook_uri.as_ref(),
token,
)
.await
@ -3677,11 +3523,9 @@ impl Inner {
.ts_server
.get_encoded_semantic_classifications(
self.snapshot(),
&module.specifier,
&module,
module.line_index.offset_tsc(params.range.start)?
..module.line_index.offset_tsc(params.range.end)?,
module.scope.as_ref(),
module.notebook_uri.as_ref(),
token,
)
.await
@ -3744,13 +3588,11 @@ impl Inner {
.ts_server
.get_signature_help_items(
self.snapshot(),
&module.specifier,
&module,
module
.line_index
.offset_tsc(params.text_document_position_params.position)?,
options,
module.scope.as_ref(),
module.notebook_uri.as_ref(),
token,
)
.await
@ -3822,26 +3664,12 @@ impl Inner {
if options.enabled == UpdateImportsOnFileMoveEnabled::Never {
continue;
}
let format_code_settings = (&self
.config
.tree
.fmt_config_for_specifier(&module.specifier)
.options)
.into();
let changes = self
.ts_server
.get_edits_for_file_rename(
self.snapshot(),
&module.specifier,
&module,
&uri_to_url(&Uri::from_str(&rename.new_uri).unwrap()),
format_code_settings,
tsc::UserPreferences {
allow_text_changes_in_new_files: Some(true),
..Default::default()
},
scope.as_ref(),
// TODO(nayeemrmn): Support notebook scopes here.
None,
token,
)
.await
@ -3887,7 +3715,6 @@ impl Inner {
params.query.clone(),
// this matches vscode's hard coded result count
Some(256),
None,
scope.as_ref(),
// TODO(nayeemrmn): Support notebook scopes here.
None,
@ -3925,14 +3752,13 @@ impl Inner {
#[cfg_attr(feature = "lsp-tracing", tracing::instrument(skip_all))]
fn project_changed(
&mut self,
changed_specifiers: impl IntoIterator<Item = (Arc<Url>, ChangeKind)>,
documents: Vec<(Document, ChangeKind)>,
scopes_change: ProjectScopesChange,
) {
self.project_version += 1; // increment before getting the snapshot
let changed_specifiers = changed_specifiers.into_iter().collect::<Vec<_>>();
self.ts_server.project_changed(
self.snapshot(),
changed_specifiers.iter().map(|(u, k)| (u.as_ref(), *k)),
&documents,
matches!(scopes_change, ProjectScopesChange::Config).then(|| {
self
.config
@ -3961,6 +3787,9 @@ impl Inner {
.collect()
}),
);
// Invalidate the weak references of `documents` before removing expired
// entries.
drop(documents);
self.document_modules.remove_expired_modules();
}
@ -4660,7 +4489,7 @@ impl Inner {
self.resolver.did_cache();
self.refresh_dep_info().await;
self.diagnostics_server.invalidate_all();
self.project_changed([], ProjectScopesChange::Config);
self.project_changed(vec![], ProjectScopesChange::Config);
self.ts_server.cleanup_semantic_cache(self.snapshot()).await;
self.send_diagnostics_update();
self.send_testing_update();
@ -4812,18 +4641,7 @@ impl Inner {
})?;
let maybe_inlay_hints = self
.ts_server
.provide_inlay_hints(
self.snapshot(),
&module.specifier,
text_span,
tsc::UserPreferences::from_config_for_specifier(
&self.config,
&module.specifier,
),
module.scope.as_ref(),
module.notebook_uri.as_ref(),
token,
)
.provide_inlay_hints(self.snapshot(), &module, text_span, token)
.await
.map_err(|err| {
if token.is_cancelled() {

File diff suppressed because it is too large Load diff