diff options
author | David Sherret <dsherret@users.noreply.github.com> | 2021-11-12 11:42:04 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-12 11:42:04 -0500 |
commit | 28dbb4a95e569772600ae28ae4fe8b6fa2a4d2af (patch) | |
tree | 328904cc938b6c3bb3ce9b63d325115284cb5aed /cli/lsp/tsc.rs | |
parent | fdf890a68d3d54d40c766fd78faeccb20bd2e2c6 (diff) |
refactor(lsp): prefer using document instead of documents collection (#12720)
Diffstat (limited to 'cli/lsp/tsc.rs')
-rw-r--r-- | cli/lsp/tsc.rs | 147 |
1 files changed, 99 insertions, 48 deletions
diff --git a/cli/lsp/tsc.rs b/cli/lsp/tsc.rs index fc3695a5b..9350d6f19 100644 --- a/cli/lsp/tsc.rs +++ b/cli/lsp/tsc.rs @@ -119,25 +119,58 @@ impl TsServer { } } +#[derive(Debug, Clone)] +struct AssetDocumentInner { + text: Arc<String>, + length: usize, + line_index: Arc<LineIndex>, + maybe_navigation_tree: Option<Arc<NavigationTree>>, +} + /// An lsp representation of an asset in memory, that has either been retrieved /// from static assets built into Rust, or static assets built into tsc. #[derive(Debug, Clone)] -pub struct AssetDocument { - pub text: Arc<String>, - pub length: usize, - pub line_index: Arc<LineIndex>, - pub maybe_navigation_tree: Option<Arc<NavigationTree>>, -} +pub struct AssetDocument(Arc<AssetDocumentInner>); impl AssetDocument { - pub fn new<T: AsRef<str>>(text: T) -> Self { + pub fn new(text: impl AsRef<str>) -> Self { let text = text.as_ref(); - Self { + Self(Arc::new(AssetDocumentInner { text: Arc::new(text.to_string()), length: text.encode_utf16().count(), line_index: Arc::new(LineIndex::new(text)), maybe_navigation_tree: None, - } + })) + } + + pub fn with_navigation_tree( + &self, + tree: Arc<NavigationTree>, + ) -> AssetDocument { + AssetDocument(Arc::new(AssetDocumentInner { + maybe_navigation_tree: Some(tree), + ..(*self.0).clone() + })) + } + + pub fn text(&self) -> Arc<String> { + self.0.text.clone() + } + + pub fn text_str(&self) -> &str { + self.0.text.as_str() + } + + pub fn length(&self) -> usize { + self.0.length + } + + pub fn line_index(&self) -> Arc<LineIndex> { + self.0.line_index.clone() + } + + pub fn maybe_navigation_tree(&self) -> Option<Arc<NavigationTree>> { + self.0.maybe_navigation_tree.clone() } } @@ -176,14 +209,6 @@ impl Assets { self.0.insert(k, v) } - pub fn get_navigation_tree( - &self, - specifier: &ModuleSpecifier, - ) -> Option<Arc<NavigationTree>> { - let doc = self.0.get(specifier).map(|v| v.as_ref()).flatten()?; - doc.maybe_navigation_tree.as_ref().cloned() - } - pub fn set_navigation_tree( &mut self, specifier: &ModuleSpecifier, @@ -196,7 +221,7 @@ impl Assets { let doc = maybe_doc .as_mut() .ok_or_else(|| anyhow!("Cannot get doc mutable"))?; - doc.maybe_navigation_tree = Some(navigation_tree); + *doc = doc.with_navigation_tree(navigation_tree); Ok(()) } } @@ -605,10 +630,11 @@ impl DocumentSpan { language_server: &mut language_server::Inner, ) -> Option<lsp::LocationLink> { let target_specifier = normalize_specifier(&self.file_name).ok()?; - let target_line_index = language_server - .get_line_index(target_specifier.clone()) + let target_asset_or_doc = language_server + .get_asset_or_document(&target_specifier) .await .ok()?; + let target_line_index = target_asset_or_doc.line_index(); let target_uri = language_server .url_map .normalize_specifier(&target_specifier) @@ -854,6 +880,8 @@ impl RenameLocations { for location in self.locations.iter() { let specifier = normalize_specifier(&location.document_span.file_name)?; let uri = language_server.url_map.normalize_specifier(&specifier)?; + let asset_or_doc = + language_server.get_asset_or_document(&specifier).await?; // ensure TextDocumentEdit for `location.file_name`. if text_document_edit_map.get(&uri).is_none() { @@ -862,7 +890,7 @@ impl RenameLocations { lsp::TextDocumentEdit { text_document: lsp::OptionalVersionedTextDocumentIdentifier { uri: uri.clone(), - version: language_server.document_version(&specifier), + version: asset_or_doc.document_version(), }, edits: Vec::<lsp::OneOf<lsp::TextEdit, lsp::AnnotatedTextEdit>>::new(), @@ -876,7 +904,7 @@ impl RenameLocations { range: location .document_span .text_span - .to_range(language_server.get_line_index(specifier.clone()).await?), + .to_range(asset_or_doc.line_index()), new_text: new_name.to_string(), })); } @@ -1018,16 +1046,17 @@ impl FileTextChanges { language_server: &mut language_server::Inner, ) -> Result<lsp::TextDocumentEdit, AnyError> { let specifier = normalize_specifier(&self.file_name)?; - let line_index = language_server.get_line_index(specifier.clone()).await?; + let asset_or_doc = + language_server.get_asset_or_document(&specifier).await?; let edits = self .text_changes .iter() - .map(|tc| tc.as_text_edit(line_index.clone())) + .map(|tc| tc.as_text_edit(asset_or_doc.line_index())) .collect(); Ok(lsp::TextDocumentEdit { text_document: lsp::OptionalVersionedTextDocumentIdentifier { uri: specifier.clone(), - version: language_server.document_version(&specifier), + version: asset_or_doc.document_version(), }, edits, }) @@ -1039,11 +1068,17 @@ impl FileTextChanges { ) -> Result<Vec<lsp::DocumentChangeOperation>, AnyError> { let mut ops = Vec::<lsp::DocumentChangeOperation>::new(); let specifier = normalize_specifier(&self.file_name)?; - let line_index = if !self.is_new_file.unwrap_or(false) { - language_server.get_line_index(specifier.clone()).await? + let maybe_asset_or_document = if !self.is_new_file.unwrap_or(false) { + let asset_or_doc = + language_server.get_asset_or_document(&specifier).await?; + Some(asset_or_doc) } else { - Arc::new(LineIndex::new("")) + None }; + let line_index = maybe_asset_or_document + .as_ref() + .map(|d| d.line_index()) + .unwrap_or_else(|| Arc::new(LineIndex::new(""))); if self.is_new_file.unwrap_or(false) { ops.push(lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create( @@ -1066,7 +1101,9 @@ impl FileTextChanges { ops.push(lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit { text_document: lsp::OptionalVersionedTextDocumentIdentifier { uri: specifier.clone(), - version: language_server.document_version(&specifier), + version: maybe_asset_or_document + .map(|d| d.document_version()) + .flatten(), }, edits, })); @@ -1354,13 +1391,13 @@ impl CallHierarchyItem { maybe_root_path: Option<&Path>, ) -> Option<lsp::CallHierarchyItem> { let target_specifier = normalize_specifier(&self.file).ok()?; - let target_line_index = language_server - .get_line_index(target_specifier) + let target_asset_or_doc = language_server + .get_asset_or_document(&target_specifier) .await .ok()?; Some(self.to_call_hierarchy_item( - target_line_index, + target_asset_or_doc.line_index(), language_server, maybe_root_path, )) @@ -1455,21 +1492,21 @@ impl CallHierarchyIncomingCall { maybe_root_path: Option<&Path>, ) -> Option<lsp::CallHierarchyIncomingCall> { let target_specifier = normalize_specifier(&self.from.file).ok()?; - let target_line_index = language_server - .get_line_index(target_specifier) + let target_asset_or_doc = language_server + .get_asset_or_document(&target_specifier) .await .ok()?; Some(lsp::CallHierarchyIncomingCall { from: self.from.to_call_hierarchy_item( - target_line_index.clone(), + target_asset_or_doc.line_index(), language_server, maybe_root_path, ), from_ranges: self .from_spans .iter() - .map(|span| span.to_range(target_line_index.clone())) + .map(|span| span.to_range(target_asset_or_doc.line_index())) .collect(), }) } @@ -1490,14 +1527,14 @@ impl CallHierarchyOutgoingCall { maybe_root_path: Option<&Path>, ) -> Option<lsp::CallHierarchyOutgoingCall> { let target_specifier = normalize_specifier(&self.to.file).ok()?; - let target_line_index = language_server - .get_line_index(target_specifier) + let target_asset_or_doc = language_server + .get_asset_or_document(&target_specifier) .await .ok()?; Some(lsp::CallHierarchyOutgoingCall { to: self.to.to_call_hierarchy_item( - target_line_index, + target_asset_or_doc.line_index(), language_server, maybe_root_path, ), @@ -2099,10 +2136,11 @@ fn cache_snapshot( let content = state .state_snapshot .documents - .content(specifier) + .get(specifier) .ok_or_else(|| { - anyhow!("Specifier unexpectedly doesn't have content: {}", specifier) - })?; + anyhow!("Specifier unexpectedly doesn't exist: {}", specifier) + })? + .content(); state .snapshots .insert((specifier.clone(), version.into()), content.to_string()); @@ -2242,7 +2280,7 @@ fn op_get_length( let specifier = state.normalize_specifier(args.specifier)?; let r = if let Some(Some(asset)) = state.state_snapshot.assets.get(&specifier) { - Ok(asset.length) + Ok(asset.length()) } else { cache_snapshot(state, &specifier, args.version.clone())?; let content = state @@ -2275,7 +2313,7 @@ fn op_get_text( let specifier = state.normalize_specifier(args.specifier)?; let content = if let Some(Some(content)) = state.state_snapshot.assets.get(&specifier) { - content.text.as_str() + content.text_str() } else { cache_snapshot(state, &specifier, args.version.clone())?; state @@ -2296,9 +2334,9 @@ fn op_load( .performance .mark("op_load", Some(&args)); let specifier = state.normalize_specifier(args.specifier)?; - let result = state.state_snapshot.documents.content(&specifier); + let document = state.state_snapshot.documents.get(&specifier); state.state_snapshot.performance.measure(mark); - Ok(result.map(|t| t.to_string())) + Ok(document.map(|d| d.content().to_string())) } fn op_resolve( @@ -2347,7 +2385,15 @@ fn op_script_names( state: &mut State, _args: Value, ) -> Result<Vec<ModuleSpecifier>, AnyError> { - Ok(state.state_snapshot.documents.specifiers(true, true)) + Ok( + state + .state_snapshot + .documents + .documents(true, true) + .into_iter() + .map(|d| d.specifier().clone()) + .collect(), + ) } #[derive(Debug, Deserialize, Serialize)] @@ -2372,7 +2418,12 @@ fn op_script_version( Ok(None) } } else { - Ok(state.state_snapshot.documents.version(&specifier)) + let script_version = state + .state_snapshot + .documents + .get(&specifier) + .map(|d| d.script_version()); + Ok(script_version) }; state.state_snapshot.performance.measure(mark); |