diff --git a/cli/lsp/diagnostics.rs b/cli/lsp/diagnostics.rs index 1fcfc462f4..db2f4877d5 100644 --- a/cli/lsp/diagnostics.rs +++ b/cli/lsp/diagnostics.rs @@ -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)); diff --git a/cli/lsp/documents.rs b/cli/lsp/documents.rs index ff8d20f9dd..536ff16f71 100644 --- a/cli/lsp/documents.rs +++ b/cli/lsp/documents.rs @@ -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, diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs index 33bdb09a31..2b36e702f5 100644 --- a/cli/lsp/language_server.rs +++ b/cli/lsp/language_server.rs @@ -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::>(); 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::>(), - ProjectScopesChange::OpenNotebooks, - ); self.diagnostics_server.invalidate( &diagnosable_documents .iter() .map(|d| d.uri.as_ref()) .collect::>(), ); + 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::>(); 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::>(), - if config_changed { - ProjectScopesChange::Config - } else { - ProjectScopesChange::None - }, - ); self.diagnostics_server.invalidate( &diagnosable_documents .iter() .map(|(d, _)| d.uri.as_ref()) .collect::>(), ); + 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(¶ms.notebook_document.uri); let diagnosable_documents = documents - .iter() + .into_iter() .filter(|d| d.is_diagnosable()) .collect::>(); if !diagnosable_documents.is_empty() { @@ -1565,20 +1539,11 @@ impl Inner { .map(|d| d.uri.as_ref()) .collect::>(), ); - 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::>(); - // 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::>(), 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) = ¶ms.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, 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::>(); 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() { diff --git a/cli/lsp/tsc.rs b/cli/lsp/tsc.rs index 3e3d822711..66fa51fe34 100644 --- a/cli/lsp/tsc.rs +++ b/cli/lsp/tsc.rs @@ -92,6 +92,7 @@ use super::urls::uri_to_url; use super::urls::url_to_uri; use crate::args::jsr_url; use crate::args::FmtOptionsConfig; +use crate::lsp::documents::Document; use crate::lsp::logging::lsp_warn; use crate::tsc::ResolveArgs; use crate::tsc::MISSING_DEPENDENCY_SPECIFIER; @@ -140,7 +141,7 @@ pub enum IndentStyle { /// Relevant subset of https://github.com/denoland/deno/blob/v1.37.1/cli/tsc/dts/typescript.d.ts#L6658. #[derive(Clone, Debug, Default, Serialize)] #[serde(rename_all = "camelCase")] -pub struct FormatCodeSettings { +struct FormatCodeSettings { base_indent_size: Option, indent_size: Option, tab_size: Option, @@ -488,16 +489,21 @@ impl TsServer { self.start_once.is_completed() } - pub fn project_changed<'a>( + pub fn project_changed( &self, snapshot: Arc, - modified_scripts: impl IntoIterator, + documents: &[(Document, ChangeKind)], new_configs_by_scope: Option, Arc>>, new_notebook_scopes: Option, Option>>>, ) { - let modified_scripts = modified_scripts - .into_iter() - .map(|(spec, change)| (self.specifier_map.denormalize(spec), change)) + let modified_scripts = documents + .iter() + .filter_map(|(document, change_kind)| { + let specifier = + snapshot.document_modules.primary_specifier(document)?; + let specifier = self.specifier_map.denormalize(&specifier); + Some((specifier, *change_kind)) + }) .collect::>(); match &mut *self.pending_change.lock() { Some(pending_change) => { @@ -524,15 +530,19 @@ impl TsServer { pub async fn get_diagnostics( &self, snapshot: Arc, - specifiers: impl IntoIterator, - scope: Option<&Arc>, - notebook_uri: Option<&Arc>, + modules: &[Arc], token: &CancellationToken, ) -> Result<(Vec>, MaybeAmbientModules), AnyError> { - let specifiers = specifiers - .into_iter() - .map(|s| self.specifier_map.denormalize(s)) + let Some((scope, notebook_uri)) = modules + .first() + .map(|m| (m.scope.as_ref(), m.notebook_uri.as_ref())) + else { + return Ok(Default::default()); + }; + let specifiers = modules + .iter() + .map(|m| self.specifier_map.denormalize(&m.specifier)) .collect(); let req = TscRequest::GetDiagnostics((specifiers, snapshot.project_version)); @@ -576,22 +586,20 @@ impl TsServer { pub async fn find_references( &self, snapshot: Arc, - specifier: &Url, + module: &DocumentModule, position: u32, - scope: Option<&Arc>, - notebook_uri: Option<&Arc>, token: &CancellationToken, ) -> Result>, AnyError> { let req = TscRequest::FindReferences(( - self.specifier_map.denormalize(specifier), + self.specifier_map.denormalize(&module.specifier), position, )); self .request::>>( snapshot, req, - scope, - notebook_uri, + module.scope.as_ref(), + module.notebook_uri.as_ref(), token, ) .await @@ -610,16 +618,20 @@ impl TsServer { pub async fn get_navigation_tree( &self, snapshot: Arc, - specifier: &Url, - scope: Option<&Arc>, - notebook_uri: Option<&Arc>, + module: &DocumentModule, token: &CancellationToken, ) -> Result { let req = TscRequest::GetNavigationTree((self .specifier_map - .denormalize(specifier),)); + .denormalize(&module.specifier),)); self - .request(snapshot, req, scope, notebook_uri, token) + .request( + snapshot, + req, + module.scope.as_ref(), + module.notebook_uri.as_ref(), + token, + ) .await } @@ -642,18 +654,22 @@ impl TsServer { pub async fn get_quick_info( &self, snapshot: Arc, - specifier: &Url, + module: &DocumentModule, position: u32, - scope: Option<&Arc>, - notebook_uri: Option<&Arc>, token: &CancellationToken, ) -> Result, AnyError> { let req = TscRequest::GetQuickInfoAtPosition(( - self.specifier_map.denormalize(specifier), + self.specifier_map.denormalize(&module.specifier), position, )); self - .request(snapshot, req, scope, notebook_uri, token) + .request( + snapshot, + req, + module.scope.as_ref(), + module.notebook_uri.as_ref(), + token, + ) .await } @@ -662,25 +678,35 @@ impl TsServer { pub async fn get_code_fixes( &self, snapshot: Arc, - specifier: &Url, + module: &DocumentModule, range: Range, codes: Vec, - format_code_settings: FormatCodeSettings, - preferences: UserPreferences, - scope: Option<&Arc>, - notebook_uri: Option<&Arc>, token: &CancellationToken, ) -> Result, AnyError> { let req = TscRequest::GetCodeFixesAtPosition(Box::new(( - self.specifier_map.denormalize(specifier), + self.specifier_map.denormalize(&module.specifier), range.start, range.end, codes, - format_code_settings, - preferences, + (&snapshot + .config + .tree + .fmt_config_for_specifier(&module.specifier) + .options) + .into(), + UserPreferences::from_config_for_specifier( + &snapshot.config, + &module.specifier, + ), ))); self - .request::>(snapshot, req, scope, notebook_uri, token) + .request::>( + snapshot, + req, + module.scope.as_ref(), + module.notebook_uri.as_ref(), + token, + ) .await .and_then(|mut actions| { for action in &mut actions { @@ -695,13 +721,10 @@ impl TsServer { pub async fn get_applicable_refactors( &self, snapshot: Arc, - specifier: &Url, + module: &DocumentModule, range: Range, - preferences: Option, trigger_kind: Option, only: String, - scope: Option<&Arc>, - notebook_uri: Option<&Arc>, token: &CancellationToken, ) -> Result, LspError> { let trigger_kind = trigger_kind.map(|reason| match reason { @@ -710,14 +733,23 @@ impl TsServer { _ => unreachable!(), }); let req = TscRequest::GetApplicableRefactors(Box::new(( - self.specifier_map.denormalize(specifier), + self.specifier_map.denormalize(&module.specifier), range.into(), - preferences.unwrap_or_default(), + UserPreferences::from_config_for_specifier( + &snapshot.config, + &module.specifier, + ), trigger_kind, only, ))); self - .request(snapshot, req, scope, notebook_uri, token) + .request( + snapshot, + req, + module.scope.as_ref(), + module.notebook_uri.as_ref(), + token, + ) .await .map_err(|err| { log::error!("Failed to request to tsserver {}", err); @@ -730,25 +762,35 @@ impl TsServer { pub async fn get_combined_code_fix( &self, snapshot: Arc, - specifier: &Url, + module: &DocumentModule, fix_id: &str, - format_code_settings: FormatCodeSettings, - preferences: UserPreferences, - scope: Option<&Arc>, - notebook_uri: Option<&Arc>, token: &CancellationToken, ) -> Result { let req = TscRequest::GetCombinedCodeFix(Box::new(( CombinedCodeFixScope { r#type: "file", - file_name: self.specifier_map.denormalize(specifier), + file_name: self.specifier_map.denormalize(&module.specifier), }, fix_id.to_string(), - format_code_settings, - preferences, + (&snapshot + .config + .tree + .fmt_config_for_specifier(&module.specifier) + .options) + .into(), + UserPreferences::from_config_for_specifier( + &snapshot.config, + &module.specifier, + ), ))); self - .request::(snapshot, req, scope, notebook_uri, token) + .request::( + snapshot, + req, + module.scope.as_ref(), + module.notebook_uri.as_ref(), + token, + ) .await .and_then(|mut actions| { actions.normalize(&self.specifier_map)?; @@ -761,26 +803,36 @@ impl TsServer { pub async fn get_edits_for_refactor( &self, snapshot: Arc, - specifier: &Url, - format_code_settings: FormatCodeSettings, + module: &DocumentModule, range: Range, refactor_name: String, action_name: String, - preferences: Option, - scope: Option<&Arc>, - notebook_uri: Option<&Arc>, token: &CancellationToken, ) -> Result { let req = TscRequest::GetEditsForRefactor(Box::new(( - self.specifier_map.denormalize(specifier), - format_code_settings, + self.specifier_map.denormalize(&module.specifier), + (&snapshot + .config + .tree + .fmt_config_for_specifier(&module.specifier) + .options) + .into(), range.into(), refactor_name, action_name, - preferences, + Some(UserPreferences::from_config_for_specifier( + &snapshot.config, + &module.specifier, + )), ))); self - .request::(snapshot, req, scope, notebook_uri, token) + .request::( + snapshot, + req, + module.scope.as_ref(), + module.notebook_uri.as_ref(), + token, + ) .await .and_then(|mut info| { info.normalize(&self.specifier_map)?; @@ -793,26 +845,30 @@ impl TsServer { pub async fn get_edits_for_file_rename( &self, snapshot: Arc, - old_specifier: &Url, + module: &DocumentModule, new_specifier: &Url, - format_code_settings: FormatCodeSettings, - user_preferences: UserPreferences, - scope: Option<&Arc>, - notebook_uri: Option<&Arc>, token: &CancellationToken, ) -> Result, AnyError> { let req = TscRequest::GetEditsForFileRename(Box::new(( - self.specifier_map.denormalize(old_specifier), + self.specifier_map.denormalize(&module.specifier), self.specifier_map.denormalize(new_specifier), - format_code_settings, - user_preferences, + (&snapshot + .config + .tree + .fmt_config_for_specifier(&module.specifier) + .options) + .into(), + UserPreferences::from_config_for_specifier( + &snapshot.config, + &module.specifier, + ), ))); self .request::>( snapshot, req, - scope, - notebook_uri, + module.scope.as_ref(), + module.notebook_uri.as_ref(), token, ) .await @@ -836,15 +892,13 @@ impl TsServer { pub async fn get_document_highlights( &self, snapshot: Arc, - specifier: &Url, + module: &DocumentModule, position: u32, files_to_search: Vec, - scope: Option<&Arc>, - notebook_uri: Option<&Arc>, token: &CancellationToken, ) -> Result>, AnyError> { let req = TscRequest::GetDocumentHighlights(Box::new(( - self.specifier_map.denormalize(specifier), + self.specifier_map.denormalize(&module.specifier), position, files_to_search .into_iter() @@ -852,7 +906,13 @@ impl TsServer { .collect::>(), ))); self - .request(snapshot, req, scope, notebook_uri, token) + .request( + snapshot, + req, + module.scope.as_ref(), + module.notebook_uri.as_ref(), + token, + ) .await } @@ -860,22 +920,20 @@ impl TsServer { pub async fn get_definition( &self, snapshot: Arc, - specifier: &Url, + module: &DocumentModule, position: u32, - scope: Option<&Arc>, - notebook_uri: Option<&Arc>, token: &CancellationToken, ) -> Result, AnyError> { let req = TscRequest::GetDefinitionAndBoundSpan(( - self.specifier_map.denormalize(specifier), + self.specifier_map.denormalize(&module.specifier), position, )); self .request::>( snapshot, req, - scope, - notebook_uri, + module.scope.as_ref(), + module.notebook_uri.as_ref(), token, ) .await @@ -891,22 +949,20 @@ impl TsServer { pub async fn get_type_definition( &self, snapshot: Arc, - specifier: &Url, + module: &DocumentModule, position: u32, - scope: Option<&Arc>, - notebook_uri: Option<&Arc>, token: &CancellationToken, ) -> Result>, AnyError> { let req = TscRequest::GetTypeDefinitionAtPosition(( - self.specifier_map.denormalize(specifier), + self.specifier_map.denormalize(&module.specifier), position, )); self .request::>>( snapshot, req, - scope, - notebook_uri, + module.scope.as_ref(), + module.notebook_uri.as_ref(), token, ) .await @@ -926,26 +982,36 @@ impl TsServer { pub async fn get_completions( &self, snapshot: Arc, - specifier: &Url, + module: &DocumentModule, position: u32, - options: GetCompletionsAtPositionOptions, - format_code_settings: FormatCodeSettings, - scope: Option<&Arc>, - notebook_uri: Option<&Arc>, + trigger_character: Option, + trigger_kind: Option, token: &CancellationToken, ) -> Result, AnyError> { let req = TscRequest::GetCompletionsAtPosition(Box::new(( - self.specifier_map.denormalize(specifier), + self.specifier_map.denormalize(&module.specifier), position, - options, - format_code_settings, + GetCompletionsAtPositionOptions { + user_preferences: UserPreferences::from_config_for_specifier( + &snapshot.config, + &module.specifier, + ), + trigger_character, + trigger_kind, + }, + (&snapshot + .config + .tree + .fmt_config_for_specifier(&module.specifier) + .options) + .into(), ))); self .request::>( snapshot, req, - scope, - notebook_uri, + module.scope.as_ref(), + module.notebook_uri.as_ref(), token, ) .await @@ -962,32 +1028,36 @@ impl TsServer { pub async fn get_completion_details( &self, snapshot: Arc, - specifier: &Url, + module: &DocumentModule, position: u32, name: String, - format_code_settings: Option, source: Option, - preferences: Option, data: Option, - scope: Option<&Arc>, - notebook_uri: Option<&Arc>, token: &CancellationToken, ) -> Result, AnyError> { let req = TscRequest::GetCompletionEntryDetails(Box::new(( - self.specifier_map.denormalize(specifier), + self.specifier_map.denormalize(&module.specifier), position, name, - format_code_settings.unwrap_or_default(), + (&snapshot + .config + .tree + .fmt_config_for_specifier(&module.specifier) + .options) + .into(), source, - preferences, + Some(UserPreferences::from_config_for_specifier( + &snapshot.config, + &module.specifier, + )), data, ))); self .request::>( snapshot, req, - scope, - notebook_uri, + module.scope.as_ref(), + module.notebook_uri.as_ref(), token, ) .await @@ -1003,22 +1073,20 @@ impl TsServer { pub async fn get_implementations( &self, snapshot: Arc, - specifier: &Url, + module: &DocumentModule, position: u32, - scope: Option<&Arc>, - notebook_uri: Option<&Arc>, token: &CancellationToken, ) -> Result>, AnyError> { let req = TscRequest::GetImplementationAtPosition(( - self.specifier_map.denormalize(specifier), + self.specifier_map.denormalize(&module.specifier), position, )); self .request::>>( snapshot, req, - scope, - notebook_uri, + module.scope.as_ref(), + module.notebook_uri.as_ref(), token, ) .await @@ -1037,16 +1105,20 @@ impl TsServer { pub async fn get_outlining_spans( &self, snapshot: Arc, - specifier: &Url, - scope: Option<&Arc>, - notebook_uri: Option<&Arc>, + module: &DocumentModule, token: &CancellationToken, ) -> Result, AnyError> { let req = TscRequest::GetOutliningSpans((self .specifier_map - .denormalize(specifier),)); + .denormalize(&module.specifier),)); self - .request(snapshot, req, scope, notebook_uri, token) + .request( + snapshot, + req, + module.scope.as_ref(), + module.notebook_uri.as_ref(), + token, + ) .await } @@ -1054,22 +1126,20 @@ impl TsServer { pub async fn provide_call_hierarchy_incoming_calls( &self, snapshot: Arc, - specifier: &Url, + module: &DocumentModule, position: u32, - scope: Option<&Arc>, - notebook_uri: Option<&Arc>, token: &CancellationToken, ) -> Result, AnyError> { let req = TscRequest::ProvideCallHierarchyIncomingCalls(( - self.specifier_map.denormalize(specifier), + self.specifier_map.denormalize(&module.specifier), position, )); self .request::>( snapshot, req, - scope, - notebook_uri, + module.scope.as_ref(), + module.notebook_uri.as_ref(), token, ) .await @@ -1085,22 +1155,20 @@ impl TsServer { pub async fn provide_call_hierarchy_outgoing_calls( &self, snapshot: Arc, - specifier: &Url, + module: &DocumentModule, position: u32, - scope: Option<&Arc>, - notebook_uri: Option<&Arc>, token: &CancellationToken, ) -> Result, AnyError> { let req = TscRequest::ProvideCallHierarchyOutgoingCalls(( - self.specifier_map.denormalize(specifier), + self.specifier_map.denormalize(&module.specifier), position, )); self .request::>( snapshot, req, - scope, - notebook_uri, + module.scope.as_ref(), + module.notebook_uri.as_ref(), token, ) .await @@ -1119,22 +1187,20 @@ impl TsServer { pub async fn prepare_call_hierarchy( &self, snapshot: Arc, - specifier: &Url, + module: &DocumentModule, position: u32, - scope: Option<&Arc>, - notebook_uri: Option<&Arc>, token: &CancellationToken, ) -> Result>, AnyError> { let req = TscRequest::PrepareCallHierarchy(( - self.specifier_map.denormalize(specifier), + self.specifier_map.denormalize(&module.specifier), position, )); self .request::>>( snapshot, req, - scope, - notebook_uri, + module.scope.as_ref(), + module.notebook_uri.as_ref(), token, ) .await @@ -1159,26 +1225,26 @@ impl TsServer { pub async fn find_rename_locations( &self, snapshot: Arc, - specifier: &Url, + module: &DocumentModule, position: u32, - user_preferences: UserPreferences, - scope: Option<&Arc>, - notebook_uri: Option<&Arc>, token: &CancellationToken, ) -> Result>, AnyError> { let req = TscRequest::FindRenameLocations(( - self.specifier_map.denormalize(specifier), + self.specifier_map.denormalize(&module.specifier), position, false, false, - user_preferences, + UserPreferences::from_config_for_specifier( + &snapshot.config, + &module.specifier, + ), )); self .request::>>( snapshot, req, - scope, - notebook_uri, + module.scope.as_ref(), + module.notebook_uri.as_ref(), token, ) .await @@ -1197,18 +1263,22 @@ impl TsServer { pub async fn get_smart_selection_range( &self, snapshot: Arc, - specifier: &Url, + module: &DocumentModule, position: u32, - scope: Option<&Arc>, - notebook_uri: Option<&Arc>, token: &CancellationToken, ) -> Result { let req = TscRequest::GetSmartSelectionRange(( - self.specifier_map.denormalize(specifier), + self.specifier_map.denormalize(&module.specifier), position, )); self - .request(snapshot, req, scope, notebook_uri, token) + .request( + snapshot, + req, + module.scope.as_ref(), + module.notebook_uri.as_ref(), + token, + ) .await } @@ -1216,14 +1286,12 @@ impl TsServer { pub async fn get_encoded_semantic_classifications( &self, snapshot: Arc, - specifier: &Url, + module: &DocumentModule, range: Range, - scope: Option<&Arc>, - notebook_uri: Option<&Arc>, token: &CancellationToken, ) -> Result { let req = TscRequest::GetEncodedSemanticClassifications(( - self.specifier_map.denormalize(specifier), + self.specifier_map.denormalize(&module.specifier), TextSpan { start: range.start, length: range.end - range.start, @@ -1231,7 +1299,13 @@ impl TsServer { "2020", )); self - .request(snapshot, req, scope, notebook_uri, token) + .request( + snapshot, + req, + module.scope.as_ref(), + module.notebook_uri.as_ref(), + token, + ) .await } @@ -1240,20 +1314,24 @@ impl TsServer { pub async fn get_signature_help_items( &self, snapshot: Arc, - specifier: &Url, + module: &DocumentModule, position: u32, options: SignatureHelpItemsOptions, - scope: Option<&Arc>, - notebook_uri: Option<&Arc>, token: &CancellationToken, ) -> Result, AnyError> { let req = TscRequest::GetSignatureHelpItems(( - self.specifier_map.denormalize(specifier), + self.specifier_map.denormalize(&module.specifier), position, options, )); self - .request(snapshot, req, scope, notebook_uri, token) + .request( + snapshot, + req, + module.scope.as_ref(), + module.notebook_uri.as_ref(), + token, + ) .await } @@ -1264,19 +1342,11 @@ impl TsServer { snapshot: Arc, search: String, max_result_count: Option, - file: Option, scope: Option<&Arc>, notebook_uri: Option<&Arc>, token: &CancellationToken, ) -> Result, AnyError> { - let req = TscRequest::GetNavigateToItems(( - search, - max_result_count, - file.map(|f| match resolve_url(&f) { - Ok(s) => self.specifier_map.denormalize(&s), - Err(_) => f, - }), - )); + let req = TscRequest::GetNavigateToItems((search, max_result_count, None)); self .request::>(snapshot, req, scope, notebook_uri, token) .await @@ -1296,20 +1366,26 @@ impl TsServer { pub async fn provide_inlay_hints( &self, snapshot: Arc, - specifier: &Url, + module: &DocumentModule, text_span: TextSpan, - user_preferences: UserPreferences, - scope: Option<&Arc>, - notebook_uri: Option<&Arc>, token: &CancellationToken, ) -> Result>, AnyError> { let req = TscRequest::ProvideInlayHints(( - self.specifier_map.denormalize(specifier), + self.specifier_map.denormalize(&module.specifier), text_span, - user_preferences, + UserPreferences::from_config_for_specifier( + &snapshot.config, + &module.specifier, + ), )); self - .request(snapshot, req, scope, notebook_uri, token) + .request( + snapshot, + req, + module.scope.as_ref(), + module.notebook_uri.as_ref(), + token, + ) .await } @@ -5238,7 +5314,7 @@ pub type JsxAttributeCompletionStyle = config::JsxAttributeCompletionStyle; #[derive(Debug, Default, Clone, Serialize)] #[serde(rename_all = "camelCase")] -pub struct GetCompletionsAtPositionOptions { +struct GetCompletionsAtPositionOptions { #[serde(flatten)] pub user_preferences: UserPreferences, #[serde(skip_serializing_if = "Option::is_none")] @@ -5249,7 +5325,7 @@ pub struct GetCompletionsAtPositionOptions { #[derive(Debug, Default, Clone, Serialize)] #[serde(rename_all = "camelCase")] -pub struct UserPreferences { +struct UserPreferences { #[serde(skip_serializing_if = "Option::is_none")] pub disable_suggestions: Option, #[serde(skip_serializing_if = "Option::is_none")] @@ -5507,7 +5583,7 @@ pub struct CombinedCodeFixScope { pub struct JsNull; #[derive(Debug, Clone, Serialize)] -pub enum TscRequest { +enum TscRequest { GetDiagnostics((Vec, usize)), CleanupSemanticCache, @@ -5778,7 +5854,7 @@ mod tests { use crate::lsp::text::LineIndex; async fn setup( - ts_config: Value, + deno_json_content: Value, sources: &[(&str, &str, i32, LanguageId)], ) -> (TempDir, TsServer, Arc, LspCache) { let temp_dir = TempDir::new(); @@ -5788,10 +5864,7 @@ mod tests { .tree .inject_config_file( deno_config::deno_json::ConfigFile::new( - &json!({ - "compilerOptions": ts_config, - }) - .to_string(), + &deno_json_content.to_string(), temp_dir.url().join("deno.json").unwrap(), ) .unwrap(), @@ -5826,7 +5899,7 @@ mod tests { let ts_server = TsServer::new(performance); ts_server.project_changed( snapshot.clone(), - [], + &[], Some( snapshot .config @@ -5874,9 +5947,9 @@ mod tests { async fn test_get_diagnostics() { let (temp_dir, ts_server, snapshot, _) = setup( json!({ - "target": "esnext", - "noEmit": true, - "lib": [], + "compilerOptions": { + "lib": [], + }, }), &[( "a.ts", @@ -5887,14 +5960,19 @@ mod tests { ) .await; let specifier = temp_dir.url().join("a.ts").unwrap(); - let (diagnostics, _) = ts_server - .get_diagnostics( - snapshot.clone(), - [&specifier], - snapshot.config.tree.scope_for_specifier(&specifier), - None, - &Default::default(), + let module = snapshot + .document_modules + .module_for_specifier( + &specifier, + snapshot + .config + .tree + .scope_for_specifier(&specifier) + .map(|s| s.as_ref()), ) + .unwrap(); + let (diagnostics, _) = ts_server + .get_diagnostics(snapshot.clone(), &[module], &Default::default()) .await .unwrap(); assert_eq!( @@ -5923,10 +6001,9 @@ mod tests { async fn test_get_diagnostics_lib() { let (temp_dir, ts_server, snapshot, _) = setup( json!({ - "target": "esnext", - "jsx": "react", - "lib": ["esnext", "dom", "deno.ns"], - "noEmit": true, + "compilerOptions": { + "lib": ["dom"], + }, }), &[( "a.ts", @@ -5937,14 +6014,19 @@ mod tests { ) .await; let specifier = temp_dir.url().join("a.ts").unwrap(); - let (diagnostics, _) = ts_server - .get_diagnostics( - snapshot.clone(), - [&specifier], - snapshot.config.tree.scope_for_specifier(&specifier), - None, - &Default::default(), + let module = snapshot + .document_modules + .module_for_specifier( + &specifier, + snapshot + .config + .tree + .scope_for_specifier(&specifier) + .map(|s| s.as_ref()), ) + .unwrap(); + let (diagnostics, _) = ts_server + .get_diagnostics(snapshot.clone(), &[module], &Default::default()) .await .unwrap(); assert_eq!(json!(diagnostics), json!([[]])); @@ -5953,11 +6035,7 @@ mod tests { #[tokio::test] async fn test_module_resolution() { let (temp_dir, ts_server, snapshot, _) = setup( - json!({ - "target": "esnext", - "lib": ["deno.ns", "deno.window"], - "noEmit": true, - }), + json!({}), &[( "a.ts", r#" @@ -5973,14 +6051,19 @@ mod tests { ) .await; let specifier = temp_dir.url().join("a.ts").unwrap(); - let (diagnostics, _ambient) = ts_server - .get_diagnostics( - snapshot.clone(), - [&specifier], - snapshot.config.tree.scope_for_specifier(&specifier), - None, - &Default::default(), + let module = snapshot + .document_modules + .module_for_specifier( + &specifier, + snapshot + .config + .tree + .scope_for_specifier(&specifier) + .map(|s| s.as_ref()), ) + .unwrap(); + let (diagnostics, _ambient) = ts_server + .get_diagnostics(snapshot.clone(), &[module], &Default::default()) .await .unwrap(); assert_eq!(json!(diagnostics), json!([[]])); @@ -5989,11 +6072,7 @@ mod tests { #[tokio::test] async fn test_bad_module_specifiers() { let (temp_dir, ts_server, snapshot, _) = setup( - json!({ - "target": "esnext", - "lib": ["deno.ns", "deno.window"], - "noEmit": true, - }), + json!({}), &[( "a.ts", r#" @@ -6005,14 +6084,19 @@ mod tests { ) .await; let specifier = temp_dir.url().join("a.ts").unwrap(); - let (diagnostics, _ambient) = ts_server - .get_diagnostics( - snapshot.clone(), - [&specifier], - snapshot.config.tree.scope_for_specifier(&specifier), - None, - &Default::default(), + let module = snapshot + .document_modules + .module_for_specifier( + &specifier, + snapshot + .config + .tree + .scope_for_specifier(&specifier) + .map(|s| s.as_ref()), ) + .unwrap(); + let (diagnostics, _ambient) = ts_server + .get_diagnostics(snapshot.clone(), &[module], &Default::default()) .await .unwrap(); assert_eq!( @@ -6041,11 +6125,7 @@ mod tests { #[tokio::test] async fn test_remote_modules() { let (temp_dir, ts_server, snapshot, _) = setup( - json!({ - "target": "esnext", - "lib": ["deno.ns", "deno.window"], - "noEmit": true, - }), + json!({}), &[( "a.ts", r#" @@ -6061,14 +6141,19 @@ mod tests { ) .await; let specifier = temp_dir.url().join("a.ts").unwrap(); - let (diagnostics, _ambient) = ts_server - .get_diagnostics( - snapshot.clone(), - [&specifier], - snapshot.config.tree.scope_for_specifier(&specifier), - None, - &Default::default(), + let module = snapshot + .document_modules + .module_for_specifier( + &specifier, + snapshot + .config + .tree + .scope_for_specifier(&specifier) + .map(|s| s.as_ref()), ) + .unwrap(); + let (diagnostics, _ambient) = ts_server + .get_diagnostics(snapshot.clone(), &[module], &Default::default()) .await .unwrap(); assert_eq!(json!(diagnostics), json!([[]])); @@ -6077,11 +6162,7 @@ mod tests { #[tokio::test] async fn test_partial_modules() { let (temp_dir, ts_server, snapshot, _) = setup( - json!({ - "target": "esnext", - "lib": ["deno.ns", "deno.window"], - "noEmit": true, - }), + json!({}), &[( "a.ts", r#" @@ -6100,14 +6181,19 @@ mod tests { ) .await; let specifier = temp_dir.url().join("a.ts").unwrap(); - let (diagnostics, _ambient) = ts_server - .get_diagnostics( - snapshot.clone(), - [&specifier], - snapshot.config.tree.scope_for_specifier(&specifier), - None, - &Default::default(), + let module = snapshot + .document_modules + .module_for_specifier( + &specifier, + snapshot + .config + .tree + .scope_for_specifier(&specifier) + .map(|s| s.as_ref()), ) + .unwrap(); + let (diagnostics, _ambient) = ts_server + .get_diagnostics(snapshot.clone(), &[module], &Default::default()) .await .unwrap(); assert_eq!( @@ -6151,11 +6237,7 @@ mod tests { #[tokio::test] async fn test_no_debug_failure() { let (temp_dir, ts_server, snapshot, _) = setup( - json!({ - "target": "esnext", - "lib": ["deno.ns", "deno.window"], - "noEmit": true, - }), + json!({}), &[( "a.ts", r#"const url = new URL("b.js", import."#, @@ -6165,14 +6247,19 @@ mod tests { ) .await; let specifier = temp_dir.url().join("a.ts").unwrap(); - let (diagnostics, _ambient) = ts_server - .get_diagnostics( - snapshot.clone(), - [&specifier], - snapshot.config.tree.scope_for_specifier(&specifier), - None, - &Default::default(), + let module = snapshot + .document_modules + .module_for_specifier( + &specifier, + snapshot + .config + .tree + .scope_for_specifier(&specifier) + .map(|s| s.as_ref()), ) + .unwrap(); + let (diagnostics, _ambient) = ts_server + .get_diagnostics(snapshot.clone(), &[module], &Default::default()) .await .unwrap(); assert_eq!( @@ -6200,11 +6287,7 @@ mod tests { #[tokio::test] async fn test_modify_sources() { let (temp_dir, ts_server, snapshot, cache) = setup( - json!({ - "target": "esnext", - "lib": ["deno.ns", "deno.window"], - "noEmit": true, - }), + json!({}), &[( "a.ts", r#" @@ -6218,25 +6301,28 @@ mod tests { )], ) .await; - let specifier_dep = + let specifier = temp_dir.url().join("a.ts").unwrap(); + let scope = snapshot + .config + .tree + .scope_for_specifier(&specifier) + .map(|s| s.as_ref()); + let dep_specifier = resolve_url("https://deno.land/x/example/a.ts").unwrap(); cache .global() .set( - &specifier_dep, + &dep_specifier, Default::default(), b"export const b = \"b\";\n", ) .unwrap(); - let specifier = temp_dir.url().join("a.ts").unwrap(); + let module = snapshot + .document_modules + .module_for_specifier(&specifier, scope) + .unwrap(); let (diagnostics, _) = ts_server - .get_diagnostics( - snapshot.clone(), - [&specifier], - snapshot.config.tree.scope_for_specifier(&specifier), - None, - &Default::default(), - ) + .get_diagnostics(snapshot.clone(), &[module], &Default::default()) .await .unwrap(); assert_eq!( @@ -6259,22 +6345,19 @@ mod tests { } ]]), ); + let dep_document = snapshot + .document_modules + .documents + .get_for_specifier(&dep_specifier, scope, &cache) + .unwrap(); cache .global() .set( - &specifier_dep, + &dep_specifier, Default::default(), b"export const b = \"b\";\n\nexport const a = \"b\";\n", ) .unwrap(); - snapshot.document_modules.release( - &specifier_dep, - snapshot - .config - .tree - .scope_for_specifier(&specifier) - .map(|s| s.as_ref()), - ); let snapshot = { Arc::new(StateSnapshot { project_version: snapshot.project_version + 1, @@ -6283,22 +6366,27 @@ mod tests { }; ts_server.project_changed( snapshot.clone(), - [(&specifier_dep, ChangeKind::Opened)], + &[(dep_document, ChangeKind::Modified)], None, None, ); - let specifier = temp_dir.url().join("a.ts").unwrap(); + snapshot.document_modules.release( + &dep_specifier, + snapshot + .config + .tree + .scope_for_specifier(&specifier) + .map(|s| s.as_ref()), + ); + let module = snapshot + .document_modules + .module_for_specifier(&specifier, scope) + .unwrap(); let (diagnostics, _) = ts_server - .get_diagnostics( - snapshot.clone(), - [&specifier], - snapshot.config.tree.scope_for_specifier(&specifier), - None, - &Default::default(), - ) + .get_diagnostics(snapshot.clone(), &[module], &Default::default()) .await .unwrap(); - assert_eq!(json!(diagnostics), json!([[]]),); + assert_eq!(json!(diagnostics), json!([[]])); } #[test] @@ -6346,31 +6434,26 @@ mod tests { character: 16, }) .unwrap(); - let (temp_dir, ts_server, snapshot, _) = setup( - json!({ - "target": "esnext", - "lib": ["deno.ns", "deno.window"], - "noEmit": true, - }), - &[("a.ts", fixture, 1, LanguageId::TypeScript)], - ) - .await; + let (temp_dir, ts_server, snapshot, _) = + setup(json!({}), &[("a.ts", fixture, 1, LanguageId::TypeScript)]).await; let specifier = temp_dir.url().join("a.ts").unwrap(); + let module = snapshot + .document_modules + .module_for_specifier( + &specifier, + snapshot + .config + .tree + .scope_for_specifier(&specifier) + .map(|s| s.as_ref()), + ) + .unwrap(); let info = ts_server .get_completions( snapshot.clone(), - &specifier, + &module, position, - GetCompletionsAtPositionOptions { - user_preferences: UserPreferences { - include_completions_with_insert_text: Some(true), - ..Default::default() - }, - trigger_character: Some(".".to_string()), - trigger_kind: None, - }, - Default::default(), - snapshot.config.tree.scope_for_specifier(&specifier), + Some(".".to_string()), None, &Default::default(), ) @@ -6381,15 +6464,11 @@ mod tests { let details = ts_server .get_completion_details( snapshot.clone(), - &specifier, + &module, position, "log".to_string(), None, None, - None, - None, - snapshot.config.tree.scope_for_specifier(&specifier), - None, &Default::default(), ) .await @@ -6534,9 +6613,10 @@ mod tests { .unwrap(); let (temp_dir, ts_server, snapshot, _) = setup( json!({ - "target": "esnext", - "lib": ["deno.ns", "deno.window"], - "noEmit": true, + "fmt": { + "semiColons": false, + "singleQuote": true, + }, }), &[ ("a.ts", fixture_a, 1, LanguageId::TypeScript), @@ -6545,27 +6625,23 @@ mod tests { ) .await; let specifier = temp_dir.url().join("a.ts").unwrap(); - let fmt_options_config = FmtOptionsConfig { - semi_colons: Some(false), - single_quote: Some(true), - ..Default::default() - }; + let module = snapshot + .document_modules + .module_for_specifier( + &specifier, + snapshot + .config + .tree + .scope_for_specifier(&specifier) + .map(|s| s.as_ref()), + ) + .unwrap(); let info = ts_server .get_completions( snapshot.clone(), - &specifier, + &module, position, - GetCompletionsAtPositionOptions { - user_preferences: UserPreferences { - quote_preference: Some((&fmt_options_config).into()), - include_completions_for_module_exports: Some(true), - include_completions_with_insert_text: Some(true), - ..Default::default() - }, - ..Default::default() - }, - FormatCodeSettings::from(&fmt_options_config), - snapshot.config.tree.scope_for_specifier(&specifier), + None, None, &Default::default(), ) @@ -6580,18 +6656,11 @@ mod tests { let details = ts_server .get_completion_details( snapshot.clone(), - &specifier, + &module, position, entry.name.clone(), - Some(FormatCodeSettings::from(&fmt_options_config)), entry.source.clone(), - Some(UserPreferences { - quote_preference: Some((&fmt_options_config).into()), - ..Default::default() - }), entry.data.clone(), - snapshot.config.tree.scope_for_specifier(&specifier), - None, &Default::default(), ) .await @@ -6643,26 +6712,30 @@ mod tests { #[tokio::test] async fn test_get_edits_for_file_rename() { let (temp_dir, ts_server, snapshot, _) = setup( - json!({ - "target": "esnext", - "lib": ["deno.ns", "deno.window"], - "noEmit": true, - }), + json!({}), &[ ("a.ts", r#"import "./b.ts";"#, 1, LanguageId::TypeScript), ("b.ts", r#""#, 1, LanguageId::TypeScript), ], ) .await; + let specifier = temp_dir.url().join("b.ts").unwrap(); + let module = snapshot + .document_modules + .module_for_specifier( + &specifier, + snapshot + .config + .tree + .scope_for_specifier(&specifier) + .map(|s| s.as_ref()), + ) + .unwrap(); let changes = ts_server .get_edits_for_file_rename( snapshot, - &temp_dir.url().join("b.ts").unwrap(), + &module, &temp_dir.url().join("🦕.ts").unwrap(), - FormatCodeSettings::default(), - UserPreferences::default(), - Some(&Arc::new(temp_dir.url())), - None, &Default::default(), ) .await @@ -6715,15 +6788,8 @@ mod tests { #[tokio::test] async fn resolve_unknown_dependency() { - let (temp_dir, _, snapshot, _) = setup( - json!({ - "target": "esnext", - "lib": ["deno.ns", "deno.window"], - "noEmit": true, - }), - &[("a.ts", "", 1, LanguageId::TypeScript)], - ) - .await; + let (temp_dir, _, snapshot, _) = + setup(json!({}), &[("a.ts", "", 1, LanguageId::TypeScript)]).await; let mut state = setup_op_state(snapshot); let resolved = op_resolve_inner( &mut state,