summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/lsp/code_lens.rs21
-rw-r--r--cli/lsp/diagnostics.rs6
-rw-r--r--cli/lsp/language_server.rs525
-rw-r--r--cli/lsp/tsc.rs443
-rw-r--r--cli/npm/cache.rs15
5 files changed, 628 insertions, 382 deletions
diff --git a/cli/lsp/code_lens.rs b/cli/lsp/code_lens.rs
index fd7f35006..c451e30bd 100644
--- a/cli/lsp/code_lens.rs
+++ b/cli/lsp/code_lens.rs
@@ -230,13 +230,14 @@ async fn resolve_implementation_code_lens(
) -> Result<lsp::CodeLens, AnyError> {
let asset_or_doc = language_server.get_asset_or_document(&data.specifier)?;
let line_index = asset_or_doc.line_index();
- let req = tsc::RequestMethod::GetImplementation((
- data.specifier.clone(),
- line_index.offset_tsc(code_lens.range.start)?,
- ));
- let snapshot = language_server.snapshot();
- let maybe_implementations: Option<Vec<tsc::ImplementationLocation>> =
- language_server.ts_server.request(snapshot, req).await?;
+ let maybe_implementations = language_server
+ .ts_server
+ .get_implementations(
+ language_server.snapshot(),
+ data.specifier.clone(),
+ line_index.offset_tsc(code_lens.range.start)?,
+ )
+ .await?;
if let Some(implementations) = maybe_implementations {
let mut locations = Vec::new();
for implementation in implementations {
@@ -325,12 +326,12 @@ async fn resolve_references_code_lens(
let asset_or_document =
language_server.get_asset_or_document(&data.specifier)?;
let line_index = asset_or_document.line_index();
- let snapshot = language_server.snapshot();
+
let maybe_referenced_symbols = language_server
.ts_server
.find_references(
- snapshot,
- &data.specifier,
+ language_server.snapshot(),
+ data.specifier.clone(),
line_index.offset_tsc(code_lens.range.start)?,
)
.await?;
diff --git a/cli/lsp/diagnostics.rs b/cli/lsp/diagnostics.rs
index 7d13cfdb5..0f96a498b 100644
--- a/cli/lsp/diagnostics.rs
+++ b/cli/lsp/diagnostics.rs
@@ -50,7 +50,6 @@ pub type DiagnosticRecord =
pub type DiagnosticVec = Vec<DiagnosticRecord>;
type DiagnosticMap =
HashMap<ModuleSpecifier, (Option<i32>, Vec<lsp::Diagnostic>)>;
-type TsDiagnosticsMap = HashMap<String, Vec<crate::tsc::Diagnostic>>;
type DiagnosticsByVersionMap = HashMap<Option<i32>, Vec<lsp::Diagnostic>>;
#[derive(Clone)]
@@ -539,10 +538,9 @@ async fn generate_ts_diagnostics(
let (enabled_specifiers, disabled_specifiers) = specifiers
.into_iter()
.partition::<Vec<_>, _>(|s| config.specifier_enabled(s));
- let ts_diagnostics_map: TsDiagnosticsMap = if !enabled_specifiers.is_empty() {
- let req = tsc::RequestMethod::GetDiagnostics(enabled_specifiers);
+ let ts_diagnostics_map = if !enabled_specifiers.is_empty() {
ts_server
- .request_with_cancellation(snapshot.clone(), req, token)
+ .get_diagnostics(snapshot.clone(), enabled_specifiers, token)
.await?
} else {
Default::default()
diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs
index 7fe986bfe..de5cd6f09 100644
--- a/cli/lsp/language_server.rs
+++ b/cli/lsp/language_server.rs
@@ -578,10 +578,7 @@ impl Inner {
} else {
let navigation_tree: tsc::NavigationTree = self
.ts_server
- .request(
- self.snapshot(),
- tsc::RequestMethod::GetNavigationTree(specifier.clone()),
- )
+ .get_navigation_tree(self.snapshot(), specifier.clone())
.await?;
let navigation_tree = Arc::new(navigation_tree);
match asset_or_doc {
@@ -1051,10 +1048,7 @@ impl Inner {
if let Err(err) = self.merge_user_tsconfig(&mut tsconfig) {
self.client.show_message(MessageType::WARNING, err);
}
- let _ok: bool = self
- .ts_server
- .request(self.snapshot(), tsc::RequestMethod::Configure(tsconfig))
- .await?;
+ let _ok = self.ts_server.configure(self.snapshot(), tsconfig).await?;
self.performance.measure(mark);
Ok(())
}
@@ -1142,14 +1136,10 @@ impl Inner {
}
if capabilities.code_action_provider.is_some() {
- let fixable_diagnostics: Vec<String> = self
+ let fixable_diagnostics = self
.ts_server
- .request(self.snapshot(), tsc::RequestMethod::GetSupportedCodeFixes)
- .await
- .map_err(|err| {
- error!("Unable to get fixable diagnostics: {}", err);
- LspError::internal_error()
- })?;
+ .get_supported_code_fixes(self.snapshot())
+ .await?;
self.ts_fixable_diagnostics = fixable_diagnostics;
}
@@ -1383,7 +1373,7 @@ impl Inner {
self.refresh_documents_config();
self.refresh_npm_specifiers().await;
self.diagnostics_server.invalidate_all();
- self.restart_ts_server().await;
+ self.ts_server.restart(self.snapshot()).await;
self.send_diagnostics_update();
self.send_testing_update();
}
@@ -1594,18 +1584,12 @@ impl Inner {
})
} else {
let line_index = asset_or_doc.line_index();
- let req = tsc::RequestMethod::GetQuickInfo((
- specifier,
- line_index.offset_tsc(params.text_document_position_params.position)?,
- ));
- let maybe_quick_info: Option<tsc::QuickInfo> = self
+ let position =
+ line_index.offset_tsc(params.text_document_position_params.position)?;
+ let maybe_quick_info = self
.ts_server
- .request(self.snapshot(), req)
- .await
- .map_err(|err| {
- error!("Unable to get quick info: {}", err);
- LspError::internal_error()
- })?;
+ .get_quick_info(self.snapshot(), specifier.clone(), position)
+ .await?;
maybe_quick_info.map(|qi| qi.to_hover(line_index, self))
};
self.performance.measure(mark);
@@ -1666,24 +1650,16 @@ impl Inner {
NumberOrString::Number(code) => code.to_string(),
};
let codes = vec![code];
- let req = tsc::RequestMethod::GetCodeFixes((
- specifier.clone(),
- line_index.offset_tsc(diagnostic.range.start)?,
- line_index.offset_tsc(diagnostic.range.end)?,
- codes,
- ));
- let actions: Vec<tsc::CodeFixAction> =
- match self.ts_server.request(self.snapshot(), req).await {
- Ok(items) => items,
- Err(err) => {
- // sometimes tsc reports errors when retrieving code actions
- // because they don't reflect the current state of the document
- // so we will log them to the output, but we won't send an error
- // message back to the client.
- error!("Error getting actions from TypeScript: {}", err);
- Vec::new()
- }
- };
+ let actions = self
+ .ts_server
+ .get_code_fixes(
+ self.snapshot(),
+ specifier.clone(),
+ line_index.offset_tsc(diagnostic.range.start)?
+ ..line_index.offset_tsc(diagnostic.range.end)?,
+ codes,
+ )
+ .await;
for action in actions {
code_actions
.add_ts_fix_action(&specifier, &action, diagnostic, self)
@@ -1726,27 +1702,22 @@ impl Inner {
}
// Refactor
- let start = line_index.offset_tsc(params.range.start)?;
- let length = line_index.offset_tsc(params.range.end)? - start;
let only = params
.context
.only
.as_ref()
.and_then(|values| values.first().map(|v| v.as_str().to_owned()))
.unwrap_or_default();
- let req = tsc::RequestMethod::GetApplicableRefactors((
- specifier.clone(),
- tsc::TextSpan { start, length },
- only,
- ));
- let refactor_infos: Vec<tsc::ApplicableRefactorInfo> = self
+ let refactor_infos = self
.ts_server
- .request(self.snapshot(), req)
- .await
- .map_err(|err| {
- error!("Failed to request to tsserver {}", err);
- LspError::invalid_request()
- })?;
+ .get_applicable_refactors(
+ self.snapshot(),
+ specifier.clone(),
+ line_index.offset_tsc(params.range.start)?
+ ..line_index.offset_tsc(params.range.end)?,
+ only,
+ )
+ .await?;
let mut refactor_actions = Vec::<CodeAction>::new();
for refactor_info in refactor_infos.iter() {
refactor_actions
@@ -1788,24 +1759,15 @@ impl Inner {
let result = if kind.as_str().starts_with(CodeActionKind::QUICKFIX.as_str())
{
- let snapshot = self.snapshot();
let code_action_data: CodeActionData =
from_value(data).map_err(|err| {
error!("Unable to decode code action data: {}", err);
LspError::invalid_params("The CodeAction's data is invalid.")
})?;
- let req = tsc::RequestMethod::GetCombinedCodeFix((
- code_action_data.specifier.clone(),
- json!(code_action_data.fix_id.clone()),
- ));
- let combined_code_actions: tsc::CombinedCodeActions = self
+ let combined_code_actions = self
.ts_server
- .request(snapshot.clone(), req)
- .await
- .map_err(|err| {
- error!("Unable to get combined fix from TypeScript: {}", err);
- LspError::internal_error()
- })?;
+ .get_combined_code_fix(self.snapshot(), &code_action_data)
+ .await?;
if combined_code_actions.commands.is_some() {
error!("Deno does not support code actions with commands.");
return Err(LspError::invalid_request());
@@ -1831,7 +1793,6 @@ impl Inner {
})?;
code_action
} else if kind.as_str().starts_with(CodeActionKind::REFACTOR.as_str()) {
- let snapshot = self.snapshot();
let mut code_action = params;
let action_data: refactor::RefactorCodeActionData = from_value(data)
.map_err(|err| {
@@ -1840,19 +1801,17 @@ impl Inner {
})?;
let asset_or_doc = self.get_asset_or_document(&action_data.specifier)?;
let line_index = asset_or_doc.line_index();
- let start = line_index.offset_tsc(action_data.range.start)?;
- let length = line_index.offset_tsc(action_data.range.end)? - start;
- let req = tsc::RequestMethod::GetEditsForRefactor((
- action_data.specifier,
- tsc::TextSpan { start, length },
- action_data.refactor_name,
- action_data.action_name,
- ));
- let refactor_edit_info: tsc::RefactorEditInfo =
- self.ts_server.request(snapshot, req).await.map_err(|err| {
- error!("Failed to request to tsserver {}", err);
- LspError::invalid_request()
- })?;
+ let refactor_edit_info = self
+ .ts_server
+ .get_edits_for_refactor(
+ self.snapshot(),
+ action_data.specifier,
+ line_index.offset_tsc(action_data.range.start)?
+ ..line_index.offset_tsc(action_data.range.end)?,
+ action_data.refactor_name,
+ action_data.action_name,
+ )
+ .await?;
code_action.edit = refactor_edit_info
.to_workspace_edit(self)
.await
@@ -1950,19 +1909,15 @@ impl Inner {
let asset_or_doc = self.get_asset_or_document(&specifier)?;
let line_index = asset_or_doc.line_index();
let files_to_search = vec![specifier.clone()];
- let req = tsc::RequestMethod::GetDocumentHighlights((
- specifier,
- line_index.offset_tsc(params.text_document_position_params.position)?,
- files_to_search,
- ));
- let maybe_document_highlights: Option<Vec<tsc::DocumentHighlights>> = self
+ let maybe_document_highlights = self
.ts_server
- .request(self.snapshot(), req)
- .await
- .map_err(|err| {
- error!("Unable to get document highlights from TypeScript: {}", err);
- LspError::internal_error()
- })?;
+ .get_document_highlights(
+ self.snapshot(),
+ specifier,
+ line_index.offset_tsc(params.text_document_position_params.position)?,
+ files_to_search,
+ )
+ .await?;
if let Some(document_highlights) = maybe_document_highlights {
let result = document_highlights
@@ -1998,7 +1953,7 @@ impl Inner {
.ts_server
.find_references(
self.snapshot(),
- &specifier,
+ specifier.clone(),
line_index.offset_tsc(params.text_document_position.position)?,
)
.await?;
@@ -2050,18 +2005,14 @@ impl Inner {
let mark = self.performance.mark("goto_definition", Some(&params));
let asset_or_doc = self.get_asset_or_document(&specifier)?;
let line_index = asset_or_doc.line_index();
- let req = tsc::RequestMethod::GetDefinition((
- specifier,
- line_index.offset_tsc(params.text_document_position_params.position)?,
- ));
- let maybe_definition: Option<tsc::DefinitionInfoAndBoundSpan> = self
+ let maybe_definition = self
.ts_server
- .request(self.snapshot(), req)
- .await
- .map_err(|err| {
- error!("Unable to get definition from TypeScript: {}", err);
- LspError::internal_error()
- })?;
+ .get_definition(
+ self.snapshot(),
+ specifier,
+ line_index.offset_tsc(params.text_document_position_params.position)?,
+ )
+ .await?;
if let Some(definition) = maybe_definition {
let results = definition.to_definition(line_index, self).await;
@@ -2090,19 +2041,14 @@ impl Inner {
let mark = self.performance.mark("goto_definition", Some(&params));
let asset_or_doc = self.get_asset_or_document(&specifier)?;
let line_index = asset_or_doc.line_index();
- let req = tsc::RequestMethod::GetTypeDefinition {
- specifier,
- position: line_index
- .offset_tsc(params.text_document_position_params.position)?,
- };
- let maybe_definition_info: Option<Vec<tsc::DefinitionInfo>> = self
+ let maybe_definition_info = self
.ts_server
- .request(self.snapshot(), req)
- .await
- .map_err(|err| {
- error!("Unable to get type definition from TypeScript: {}", err);
- LspError::internal_error()
- })?;
+ .get_type_definition(
+ self.snapshot(),
+ specifier,
+ line_index.offset_tsc(params.text_document_position_params.position)?,
+ )
+ .await?;
let response = if let Some(definition_info) = maybe_definition_info {
let mut location_links = Vec::new();
@@ -2167,48 +2113,47 @@ impl Inner {
let position =
line_index.offset_tsc(params.text_document_position.position)?;
let use_snippets = self.config.client_capabilities.snippet_support;
- let req = tsc::RequestMethod::GetCompletions((
- specifier.clone(),
- position,
- tsc::GetCompletionsAtPositionOptions {
- user_preferences: tsc::UserPreferences {
- allow_incomplete_completions: Some(true),
- allow_text_changes_in_new_files: Some(specifier.scheme() == "file"),
- import_module_specifier_ending: Some(
- tsc::ImportModuleSpecifierEnding::Index,
- ),
- include_automatic_optional_chain_completions: Some(true),
- include_completions_for_import_statements: Some(
- self.config.workspace_settings().suggest.auto_imports,
- ),
- include_completions_for_module_exports: Some(true),
- include_completions_with_object_literal_method_snippets: Some(
- use_snippets,
- ),
- include_completions_with_class_member_snippets: Some(use_snippets),
- include_completions_with_insert_text: Some(true),
- include_completions_with_snippet_text: Some(use_snippets),
- jsx_attribute_completion_style: Some(
- tsc::JsxAttributeCompletionStyle::Auto,
- ),
- provide_prefix_and_suffix_text_for_rename: Some(true),
- provide_refactor_not_applicable_reason: Some(true),
- use_label_details_in_completion_entries: Some(true),
- ..Default::default()
+ let maybe_completion_info = self
+ .ts_server
+ .get_completions(
+ self.snapshot(),
+ specifier.clone(),
+ position,
+ tsc::GetCompletionsAtPositionOptions {
+ user_preferences: tsc::UserPreferences {
+ allow_incomplete_completions: Some(true),
+ allow_text_changes_in_new_files: Some(
+ specifier.scheme() == "file",
+ ),
+ import_module_specifier_ending: Some(
+ tsc::ImportModuleSpecifierEnding::Index,
+ ),
+ include_automatic_optional_chain_completions: Some(true),
+ include_completions_for_import_statements: Some(
+ self.config.workspace_settings().suggest.auto_imports,
+ ),
+ include_completions_for_module_exports: Some(true),
+ include_completions_with_object_literal_method_snippets: Some(
+ use_snippets,
+ ),
+ include_completions_with_class_member_snippets: Some(
+ use_snippets,
+ ),
+ include_completions_with_insert_text: Some(true),
+ include_completions_with_snippet_text: Some(use_snippets),
+ jsx_attribute_completion_style: Some(
+ tsc::JsxAttributeCompletionStyle::Auto,
+ ),
+ provide_prefix_and_suffix_text_for_rename: Some(true),
+ provide_refactor_not_applicable_reason: Some(true),
+ use_label_details_in_completion_entries: Some(true),
+ ..Default::default()
+ },
+ trigger_character,
+ trigger_kind,
},
- trigger_character,
- trigger_kind,
- },
- ));
- let snapshot = self.snapshot();
- let maybe_completion_info: Option<tsc::CompletionInfo> =
- match self.ts_server.request(snapshot, req).await {
- Ok(maybe_info) => maybe_info,
- Err(err) => {
- error!("Unable to get completion info from TypeScript: {:#}", err);
- None
- }
- };
+ )
+ .await;
if let Some(completions) = maybe_completion_info {
let results = completions.as_completion_response(
@@ -2241,9 +2186,10 @@ impl Inner {
})?;
if let Some(data) = &data.tsc {
let specifier = &data.specifier;
- let req = tsc::RequestMethod::GetCompletionDetails(data.into());
- let result: Result<Option<tsc::CompletionEntryDetails>, _> =
- self.ts_server.request(self.snapshot(), req).await;
+ let result = self
+ .ts_server
+ .get_completion_details(self.snapshot(), data.into())
+ .await;
match result {
Ok(maybe_completion_info) => {
if let Some(completion_info) = maybe_completion_info {
@@ -2302,18 +2248,14 @@ impl Inner {
let asset_or_doc = self.get_asset_or_document(&specifier)?;
let line_index = asset_or_doc.line_index();
- let req = tsc::RequestMethod::GetImplementation((
- specifier,
- line_index.offset_tsc(params.text_document_position_params.position)?,
- ));
- let maybe_implementations: Option<Vec<tsc::ImplementationLocation>> = self
+ let maybe_implementations = self
.ts_server
- .request(self.snapshot(), req)
- .await
- .map_err(|err| {
- error!("Failed to request to tsserver {}", err);
- LspError::invalid_request()
- })?;
+ .get_implementations(
+ self.snapshot(),
+ specifier,
+ line_index.offset_tsc(params.text_document_position_params.position)?,
+ )
+ .await?;
let result = if let Some(implementations) = maybe_implementations {
let mut links = Vec::new();
@@ -2347,15 +2289,10 @@ impl Inner {
let mark = self.performance.mark("folding_range", Some(&params));
let asset_or_doc = self.get_asset_or_document(&specifier)?;
- let req = tsc::RequestMethod::GetOutliningSpans(specifier);
- let outlining_spans: Vec<tsc::OutliningSpan> = self
+ let outlining_spans = self
.ts_server
- .request(self.snapshot(), req)
- .await
- .map_err(|err| {
- error!("Failed to request to tsserver {}", err);
- LspError::invalid_request()
- })?;
+ .get_outlining_spans(self.snapshot(), specifier)
+ .await?;
let response = if !outlining_spans.is_empty() {
Some(
@@ -2394,18 +2331,14 @@ impl Inner {
let asset_or_doc = self.get_asset_or_document(&specifier)?;
let line_index = asset_or_doc.line_index();
- let req = tsc::RequestMethod::ProvideCallHierarchyIncomingCalls((
- specifier,
- line_index.offset_tsc(params.item.selection_range.start)?,
- ));
let incoming_calls: Vec<tsc::CallHierarchyIncomingCall> = self
.ts_server
- .request(self.snapshot(), req)
- .await
- .map_err(|err| {
- error!("Failed to request to tsserver {}", err);
- LspError::invalid_request()
- })?;
+ .provide_call_hierarchy_incoming_calls(
+ self.snapshot(),
+ specifier,
+ line_index.offset_tsc(params.item.selection_range.start)?,
+ )
+ .await?;
let maybe_root_path_owned = self
.config
@@ -2442,18 +2375,14 @@ impl Inner {
let asset_or_doc = self.get_asset_or_document(&specifier)?;
let line_index = asset_or_doc.line_index();
- let req = tsc::RequestMethod::ProvideCallHierarchyOutgoingCalls((
- specifier,
- line_index.offset_tsc(params.item.selection_range.start)?,
- ));
let outgoing_calls: Vec<tsc::CallHierarchyOutgoingCall> = self
.ts_server
- .request(self.snapshot(), req)
- .await
- .map_err(|err| {
- error!("Failed to request to tsserver {}", err);
- LspError::invalid_request()
- })?;
+ .provide_call_hierarchy_outgoing_calls(
+ self.snapshot(),
+ specifier,
+ line_index.offset_tsc(params.item.selection_range.start)?,
+ )
+ .await?;
let maybe_root_path_owned = self
.config
@@ -2494,19 +2423,14 @@ impl Inner {
let asset_or_doc = self.get_asset_or_document(&specifier)?;
let line_index = asset_or_doc.line_index();
- let req = tsc::RequestMethod::PrepareCallHierarchy((
- specifier,
- line_index.offset_tsc(params.text_document_position_params.position)?,
- ));
- let maybe_one_or_many: Option<tsc::OneOrMany<tsc::CallHierarchyItem>> =
- self
- .ts_server
- .request(self.snapshot(), req)
- .await
- .map_err(|err| {
- error!("Failed to request to tsserver {}", err);
- LspError::invalid_request()
- })?;
+ let maybe_one_or_many = self
+ .ts_server
+ .prepare_call_hierarchy(
+ self.snapshot(),
+ specifier,
+ line_index.offset_tsc(params.text_document_position_params.position)?,
+ )
+ .await?;
let response = if let Some(one_or_many) = maybe_one_or_many {
let maybe_root_path_owned = self
@@ -2561,23 +2485,14 @@ impl Inner {
let asset_or_doc = self.get_asset_or_document(&specifier)?;
let line_index = asset_or_doc.line_index();
- let req = tsc::RequestMethod::FindRenameLocations {
- specifier,
- position: line_index
- .offset_tsc(params.text_document_position.position)?,
- find_in_strings: false,
- find_in_comments: false,
- provide_prefix_and_suffix_text_for_rename: false,
- };
-
- let maybe_locations: Option<Vec<tsc::RenameLocation>> = self
+ let maybe_locations = self
.ts_server
- .request(self.snapshot(), req)
- .await
- .map_err(|err| {
- error!("Failed to request to tsserver {}", err);
- LspError::invalid_request()
- })?;
+ .find_rename_locations(
+ self.snapshot(),
+ specifier,
+ line_index.offset_tsc(params.text_document_position.position)?,
+ )
+ .await?;
if let Some(locations) = maybe_locations {
let rename_locations = tsc::RenameLocations { locations };
@@ -2615,19 +2530,14 @@ impl Inner {
let mut selection_ranges = Vec::<SelectionRange>::new();
for position in params.positions {
- let req = tsc::RequestMethod::GetSmartSelectionRange((
- specifier.clone(),
- line_index.offset_tsc(position)?,
- ));
-
let selection_range: tsc::SelectionRange = self
.ts_server
- .request(self.snapshot(), req)
- .await
- .map_err(|err| {
- error!("Failed to request to tsserver {}", err);
- LspError::invalid_request()
- })?;
+ .get_smart_selection_range(
+ self.snapshot(),
+ specifier.clone(),
+ line_index.offset_tsc(position)?,
+ )
+ .await?;
selection_ranges
.push(selection_range.to_selection_range(line_index.clone()));
@@ -2653,21 +2563,14 @@ impl Inner {
let asset_or_doc = self.get_asset_or_document(&specifier)?;
let line_index = asset_or_doc.line_index();
- let req = tsc::RequestMethod::GetEncodedSemanticClassifications((
- specifier,
- tsc::TextSpan {
- start: 0,
- length: line_index.text_content_length_utf16().into(),
- },
- ));
- let semantic_classification: tsc::Classifications = self
+ let semantic_classification = self
.ts_server
- .request(self.snapshot(), req)
- .await
- .map_err(|err| {
- error!("Failed to request to tsserver {}", err);
- LspError::invalid_request()
- })?;
+ .get_encoded_semantic_classifications(
+ self.snapshot(),
+ specifier,
+ 0..line_index.text_content_length_utf16().into(),
+ )
+ .await?;
let semantic_tokens =
semantic_classification.to_semantic_tokens(&asset_or_doc, line_index)?;
@@ -2699,20 +2602,15 @@ impl Inner {
let asset_or_doc = self.get_asset_or_document(&specifier)?;
let line_index = asset_or_doc.line_index();
- let start = line_index.offset_tsc(params.range.start)?;
- let length = line_index.offset_tsc(params.range.end)? - start;
- let req = tsc::RequestMethod::GetEncodedSemanticClassifications((
- specifier,
- tsc::TextSpan { start, length },
- ));
- let semantic_classification: tsc::Classifications = self
+ let semantic_classification = self
.ts_server
- .request(self.snapshot(), req)
- .await
- .map_err(|err| {
- error!("Failed to request to tsserver {}", err);
- LspError::invalid_request()
- })?;
+ .get_encoded_semantic_classifications(
+ self.snapshot(),
+ specifier,
+ line_index.offset_tsc(params.range.start)?
+ ..line_index.offset_tsc(params.range.end)?,
+ )
+ .await?;
let semantic_tokens =
semantic_classification.to_semantic_tokens(&asset_or_doc, line_index)?;
@@ -2754,19 +2652,15 @@ impl Inner {
trigger_reason: None,
}
};
- let req = tsc::RequestMethod::GetSignatureHelpItems((
- specifier,
- line_index.offset_tsc(params.text_document_position_params.position)?,
- options,
- ));
let maybe_signature_help_items: Option<tsc::SignatureHelpItems> = self
.ts_server
- .request(self.snapshot(), req)
- .await
- .map_err(|err| {
- error!("Failed to request to tsserver: {}", err);
- LspError::invalid_request()
- })?;
+ .get_signature_help_items(
+ self.snapshot(),
+ specifier,
+ line_index.offset_tsc(params.text_document_position_params.position)?,
+ options,
+ )
+ .await?;
if let Some(signature_help_items) = maybe_signature_help_items {
let signature_help = signature_help_items.into_signature_help(self);
@@ -2784,21 +2678,18 @@ impl Inner {
) -> LspResult<Option<Vec<SymbolInformation>>> {
let mark = self.performance.mark("symbol", Some(&params));
- let req = tsc::RequestMethod::GetNavigateToItems {
- search: params.query,
- // this matches vscode's hard coded result count
- max_result_count: Some(256),
- file: None,
- };
-
- let navigate_to_items: Vec<tsc::NavigateToItem> = self
+ let navigate_to_items = self
.ts_server
- .request(self.snapshot(), req)
- .await
- .map_err(|err| {
- error!("Failed request to tsserver: {}", err);
- LspError::invalid_request()
- })?;
+ .get_navigate_to_items(
+ self.snapshot(),
+ tsc::GetNavigateToItemsArgs {
+ search: params.query,
+ // this matches vscode's hard coded result count
+ max_result_count: Some(256),
+ file: None,
+ },
+ )
+ .await?;
let maybe_symbol_information = if navigate_to_items.is_empty() {
None
@@ -3287,21 +3178,13 @@ impl Inner {
// the language server for TypeScript (as it might hold to some stale
// documents).
self.diagnostics_server.invalidate_all();
- self.restart_ts_server().await;
+ self.ts_server.restart(self.snapshot()).await;
self.send_diagnostics_update();
self.send_testing_update();
self.performance.measure(mark);
}
- async fn restart_ts_server(&self) {
- let _: bool = self
- .ts_server
- .request(self.snapshot(), tsc::RequestMethod::Restart)
- .await
- .unwrap();
- }
-
fn get_performance(&self) -> Value {
let averages = self.performance.averages();
json!({ "averages": averages })
@@ -3334,24 +3217,22 @@ impl Inner {
let mark = self.performance.mark("inlay_hint", Some(&params));
let asset_or_doc = self.get_asset_or_document(&specifier)?;
let line_index = asset_or_doc.line_index();
- let range = tsc::TextSpan::from_range(&params.range, line_index.clone())
- .map_err(|err| {
- error!("Failed to convert range to text_span: {}", err);
- LspError::internal_error()
- })?;
- let req = tsc::RequestMethod::ProvideInlayHints((
- specifier,
- range,
- workspace_settings.into(),
- ));
- let maybe_inlay_hints: Option<Vec<tsc::InlayHint>> = self
+ let text_span =
+ tsc::TextSpan::from_range(&params.range, line_index.clone()).map_err(
+ |err| {
+ error!("Failed to convert range to text_span: {}", err);
+ LspError::internal_error()
+ },
+ )?;
+ let maybe_inlay_hints = self
.ts_server
- .request(self.snapshot(), req)
- .await
- .map_err(|err| {
- error!("Unable to get inlay hints: {}", err);
- LspError::internal_error()
- })?;
+ .provide_inlay_hints(
+ self.snapshot(),
+ specifier,
+ text_span,
+ workspace_settings.into(),
+ )
+ .await?;
let maybe_inlay_hints = maybe_inlay_hints.map(|hints| {
hints
.iter()
diff --git a/cli/lsp/tsc.rs b/cli/lsp/tsc.rs
index 92407bec1..bfbb5cf9a 100644
--- a/cli/lsp/tsc.rs
+++ b/cli/lsp/tsc.rs
@@ -1,5 +1,6 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+use super::analysis::CodeActionData;
use super::code_lens;
use super::config;
use super::documents::AssetOrDocument;
@@ -53,6 +54,7 @@ use serde_repr::Serialize_repr;
use std::cmp;
use std::collections::HashMap;
use std::collections::HashSet;
+use std::ops::Range;
use std::path::Path;
use std::sync::Arc;
use std::thread;
@@ -118,7 +120,403 @@ impl TsServer {
Self(tx)
}
- pub async fn request<R>(
+ pub async fn get_diagnostics(
+ &self,
+ snapshot: Arc<StateSnapshot>,
+ specifiers: Vec<ModuleSpecifier>,
+ token: CancellationToken,
+ ) -> Result<HashMap<String, Vec<crate::tsc::Diagnostic>>, AnyError> {
+ let req = RequestMethod::GetDiagnostics(specifiers);
+ self.request_with_cancellation(snapshot, req, token).await
+ }
+
+ pub async fn find_references(
+ &self,
+ snapshot: Arc<StateSnapshot>,
+ specifier: ModuleSpecifier,
+ position: u32,
+ ) -> Result<Option<Vec<ReferencedSymbol>>, LspError> {
+ let req = RequestMethod::FindReferences {
+ specifier,
+ position,
+ };
+ self.request(snapshot, req).await.map_err(|err| {
+ log::error!("Unable to get references from TypeScript: {}", err);
+ LspError::internal_error()
+ })
+ }
+
+ pub async fn get_navigation_tree(
+ &self,
+ snapshot: Arc<StateSnapshot>,
+ specifier: ModuleSpecifier,
+ ) -> Result<NavigationTree, AnyError> {
+ self
+ .request(snapshot, RequestMethod::GetNavigationTree(specifier))
+ .await
+ }
+
+ pub async fn configure(
+ &self,
+ snapshot: Arc<StateSnapshot>,
+ tsconfig: TsConfig,
+ ) -> Result<bool, AnyError> {
+ self
+ .request(snapshot, RequestMethod::Configure(tsconfig))
+ .await
+ }
+
+ pub async fn get_supported_code_fixes(
+ &self,
+ snapshot: Arc<StateSnapshot>,
+ ) -> Result<Vec<String>, LspError> {
+ self
+ .request(snapshot, RequestMethod::GetSupportedCodeFixes)
+ .await
+ .map_err(|err| {
+ log::error!("Unable to get fixable diagnostics: {}", err);
+ LspError::internal_error()
+ })
+ }
+
+ pub async fn get_quick_info(
+ &self,
+ snapshot: Arc<StateSnapshot>,
+ specifier: ModuleSpecifier,
+ position: u32,
+ ) -> Result<Option<QuickInfo>, LspError> {
+ let req = RequestMethod::GetQuickInfo((specifier, position));
+ self.request(snapshot, req).await.map_err(|err| {
+ log::error!("Unable to get quick info: {}", err);
+ LspError::internal_error()
+ })
+ }
+
+ pub async fn get_code_fixes(
+ &self,
+ snapshot: Arc<StateSnapshot>,
+ specifier: ModuleSpecifier,
+ range: Range<u32>,
+ codes: Vec<String>,
+ ) -> Vec<CodeFixAction> {
+ let req =
+ RequestMethod::GetCodeFixes((specifier, range.start, range.end, codes));
+ match self.request(snapshot, req).await {
+ Ok(items) => items,
+ Err(err) => {
+ // sometimes tsc reports errors when retrieving code actions
+ // because they don't reflect the current state of the document
+ // so we will log them to the output, but we won't send an error
+ // message back to the client.
+ log::error!("Error getting actions from TypeScript: {}", err);
+ Vec::new()
+ }
+ }
+ }
+
+ pub async fn get_applicable_refactors(
+ &self,
+ snapshot: Arc<StateSnapshot>,
+ specifier: ModuleSpecifier,
+ range: Range<u32>,
+ only: String,
+ ) -> Result<Vec<ApplicableRefactorInfo>, LspError> {
+ let req = RequestMethod::GetApplicableRefactors((
+ specifier.clone(),
+ TextSpan {
+ start: range.start,
+ length: range.end - range.start,
+ },
+ only,
+ ));
+ self.request(snapshot, req).await.map_err(|err| {
+ log::error!("Failed to request to tsserver {}", err);
+ LspError::invalid_request()
+ })
+ }
+
+ pub async fn get_combined_code_fix(
+ &self,
+ snapshot: Arc<StateSnapshot>,
+ code_action_data: &CodeActionData,
+ ) -> Result<CombinedCodeActions, LspError> {
+ let req = RequestMethod::GetCombinedCodeFix((
+ code_action_data.specifier.clone(),
+ json!(code_action_data.fix_id.clone()),
+ ));
+ self.request(snapshot, req).await.map_err(|err| {
+ log::error!("Unable to get combined fix from TypeScript: {}", err);
+ LspError::internal_error()
+ })
+ }
+
+ pub async fn get_edits_for_refactor(
+ &self,
+ snapshot: Arc<StateSnapshot>,
+ specifier: ModuleSpecifier,
+ range: Range<u32>,
+ refactor_name: String,
+ action_name: String,
+ ) -> Result<RefactorEditInfo, LspError> {
+ let req = RequestMethod::GetEditsForRefactor((
+ specifier,
+ TextSpan {
+ start: range.start,
+ length: range.end - range.start,
+ },
+ refactor_name,
+ action_name,
+ ));
+ self.request(snapshot, req).await.map_err(|err| {
+ log::error!("Failed to request to tsserver {}", err);
+ LspError::invalid_request()
+ })
+ }
+
+ pub async fn get_document_highlights(
+ &self,
+ snapshot: Arc<StateSnapshot>,
+ specifier: ModuleSpecifier,
+ position: u32,
+ files_to_search: Vec<ModuleSpecifier>,
+ ) -> Result<Option<Vec<DocumentHighlights>>, LspError> {
+ let req = RequestMethod::GetDocumentHighlights((
+ specifier,
+ position,
+ files_to_search,
+ ));
+ self.request(snapshot, req).await.map_err(|err| {
+ log::error!("Unable to get document highlights from TypeScript: {}", err);
+ LspError::internal_error()
+ })
+ }
+
+ pub async fn get_definition(
+ &self,
+ snapshot: Arc<StateSnapshot>,
+ specifier: ModuleSpecifier,
+ position: u32,
+ ) -> Result<Option<DefinitionInfoAndBoundSpan>, LspError> {
+ let req = RequestMethod::GetDefinition((specifier, position));
+ self.request(snapshot, req).await.map_err(|err| {
+ log::error!("Unable to get definition from TypeScript: {}", err);
+ LspError::internal_error()
+ })
+ }
+
+ pub async fn get_type_definition(
+ &self,
+ snapshot: Arc<StateSnapshot>,
+ specifier: ModuleSpecifier,
+ position: u32,
+ ) -> Result<Option<Vec<DefinitionInfo>>, LspError> {
+ let req = RequestMethod::GetTypeDefinition {
+ specifier,
+ position,
+ };
+ self.request(snapshot, req).await.map_err(|err| {
+ log::error!("Unable to get type definition from TypeScript: {}", err);
+ LspError::internal_error()
+ })
+ }
+
+ pub async fn get_completions(
+ &self,
+ snapshot: Arc<StateSnapshot>,
+ specifier: ModuleSpecifier,
+ position: u32,
+ options: GetCompletionsAtPositionOptions,
+ ) -> Option<CompletionInfo> {
+ let req = RequestMethod::GetCompletions((specifier, position, options));
+ match self.request(snapshot, req).await {
+ Ok(maybe_info) => maybe_info,
+ Err(err) => {
+ log::error!("Unable to get completion info from TypeScript: {:#}", err);
+ None
+ }
+ }
+ }
+
+ pub async fn get_completion_details(
+ &self,
+ snapshot: Arc<StateSnapshot>,
+ args: GetCompletionDetailsArgs,
+ ) -> Result<Option<CompletionEntryDetails>, AnyError> {
+ let req = RequestMethod::GetCompletionDetails(args);
+ self.request(snapshot, req).await
+ }
+
+ pub async fn get_implementations(
+ &self,
+ snapshot: Arc<StateSnapshot>,
+ specifier: ModuleSpecifier,
+ position: u32,
+ ) -> Result<Option<Vec<ImplementationLocation>>, LspError> {
+ let req = RequestMethod::GetImplementation((specifier, position));
+ self.request(snapshot, req).await.map_err(|err| {
+ log::error!("Failed to request to tsserver {}", err);
+ LspError::invalid_request()
+ })
+ }
+
+ pub async fn get_outlining_spans(
+ &self,
+ snapshot: Arc<StateSnapshot>,
+ specifier: ModuleSpecifier,
+ ) -> Result<Vec<OutliningSpan>, LspError> {
+ let req = RequestMethod::GetOutliningSpans(specifier);
+ self.request(snapshot, req).await.map_err(|err| {
+ log::error!("Failed to request to tsserver {}", err);
+ LspError::invalid_request()
+ })
+ }
+
+ pub async fn provide_call_hierarchy_incoming_calls(
+ &self,
+ snapshot: Arc<StateSnapshot>,
+ specifier: ModuleSpecifier,
+ position: u32,
+ ) -> Result<Vec<CallHierarchyIncomingCall>, LspError> {
+ let req =
+ RequestMethod::ProvideCallHierarchyIncomingCalls((specifier, position));
+ self.request(snapshot, req).await.map_err(|err| {
+ log::error!("Failed to request to tsserver {}", err);
+ LspError::invalid_request()
+ })
+ }
+
+ pub async fn provide_call_hierarchy_outgoing_calls(
+ &self,
+ snapshot: Arc<StateSnapshot>,
+ specifier: ModuleSpecifier,
+ position: u32,
+ ) -> Result<Vec<CallHierarchyOutgoingCall>, LspError> {
+ let req =
+ RequestMethod::ProvideCallHierarchyOutgoingCalls((specifier, position));
+ self.request(snapshot, req).await.map_err(|err| {
+ log::error!("Failed to request to tsserver {}", err);
+ LspError::invalid_request()
+ })
+ }
+
+ pub async fn prepare_call_hierarchy(
+ &self,
+ snapshot: Arc<StateSnapshot>,
+ specifier: ModuleSpecifier,
+ position: u32,
+ ) -> Result<Option<OneOrMany<CallHierarchyItem>>, LspError> {
+ let req = RequestMethod::PrepareCallHierarchy((specifier, position));
+ self.request(snapshot, req).await.map_err(|err| {
+ log::error!("Failed to request to tsserver {}", err);
+ LspError::invalid_request()
+ })
+ }
+
+ pub async fn find_rename_locations(
+ &self,
+ snapshot: Arc<StateSnapshot>,
+ specifier: ModuleSpecifier,
+ position: u32,
+ ) -> Result<Option<Vec<RenameLocation>>, LspError> {
+ let req = RequestMethod::FindRenameLocations {
+ specifier,
+ position,
+ find_in_strings: false,
+ find_in_comments: false,
+ provide_prefix_and_suffix_text_for_rename: false,
+ };
+ self.request(snapshot, req).await.map_err(|err| {
+ log::error!("Failed to request to tsserver {}", err);
+ LspError::invalid_request()
+ })
+ }
+
+ pub async fn get_smart_selection_range(
+ &self,
+ snapshot: Arc<StateSnapshot>,
+ specifier: ModuleSpecifier,
+ position: u32,
+ ) -> Result<SelectionRange, LspError> {
+ let req = RequestMethod::GetSmartSelectionRange((specifier, position));
+
+ self.request(snapshot, req).await.map_err(|err| {
+ log::error!("Failed to request to tsserver {}", err);
+ LspError::invalid_request()
+ })
+ }
+
+ pub async fn get_encoded_semantic_classifications(
+ &self,
+ snapshot: Arc<StateSnapshot>,
+ specifier: ModuleSpecifier,
+ range: Range<u32>,
+ ) -> Result<Classifications, LspError> {
+ let req = RequestMethod::GetEncodedSemanticClassifications((
+ specifier,
+ TextSpan {
+ start: range.start,
+ length: range.end - range.start,
+ },
+ ));
+ self.request(snapshot, req).await.map_err(|err| {
+ log::error!("Failed to request to tsserver {}", err);
+ LspError::invalid_request()
+ })
+ }
+
+ pub async fn get_signature_help_items(
+ &self,
+ snapshot: Arc<StateSnapshot>,
+ specifier: ModuleSpecifier,
+ position: u32,
+ options: SignatureHelpItemsOptions,
+ ) -> Result<Option<SignatureHelpItems>, LspError> {
+ let req =
+ RequestMethod::GetSignatureHelpItems((specifier, position, options));
+ self.request(snapshot, req).await.map_err(|err| {
+ log::error!("Failed to request to tsserver: {}", err);
+ LspError::invalid_request()
+ })
+ }
+
+ pub async fn get_navigate_to_items(
+ &self,
+ snapshot: Arc<StateSnapshot>,
+ args: GetNavigateToItemsArgs,
+ ) -> Result<Vec<NavigateToItem>, LspError> {
+ let req = RequestMethod::GetNavigateToItems(args);
+ self.request(snapshot, req).await.map_err(|err| {
+ log::error!("Failed request to tsserver: {}", err);
+ LspError::invalid_request()
+ })
+ }
+
+ pub async fn provide_inlay_hints(
+ &self,
+ snapshot: Arc<StateSnapshot>,
+ specifier: ModuleSpecifier,
+ text_span: TextSpan,
+ user_preferences: UserPreferences,
+ ) -> Result<Option<Vec<InlayHint>>, LspError> {
+ let req = RequestMethod::ProvideInlayHints((
+ specifier,
+ text_span,
+ user_preferences,
+ ));
+ self.request(snapshot, req).await.map_err(|err| {
+ log::error!("Unable to get inlay hints: {}", err);
+ LspError::internal_error()
+ })
+ }
+
+ pub async fn restart(&self, snapshot: Arc<StateSnapshot>) {
+ let _: bool = self
+ .request(snapshot, RequestMethod::Restart)
+ .await
+ .unwrap();
+ }
+
+ async fn request<R>(
&self,
snapshot: Arc<StateSnapshot>,
req: RequestMethod,
@@ -131,7 +529,7 @@ impl TsServer {
.await
}
- pub async fn request_with_cancellation<R>(
+ async fn request_with_cancellation<R>(
&self,
snapshot: Arc<StateSnapshot>,
req: RequestMethod,
@@ -147,26 +545,6 @@ impl TsServer {
let value = rx.await??;
Ok(serde_json::from_value::<R>(value)?)
}
-
- // todo(dsherret): refactor the rest of the request methods to have
- // methods to call on this struct, then make `RequestMethod` and
- // friends internal
-
- pub async fn find_references(
- &self,
- snapshot: Arc<StateSnapshot>,
- specifier: &ModuleSpecifier,
- position: u32,
- ) -> Result<Option<Vec<ReferencedSymbol>>, LspError> {
- let req = RequestMethod::FindReferences {
- specifier: specifier.clone(),
- position,
- };
- self.request(snapshot, req).await.map_err(|err| {
- log::error!("Unable to get references from TypeScript: {}", err);
- LspError::internal_error()
- })
- }
}
#[derive(Debug, Clone)]
@@ -3161,9 +3539,16 @@ impl From<&CompletionItemData> for GetCompletionDetailsArgs {
}
}
+#[derive(Debug)]
+pub struct GetNavigateToItemsArgs {
+ pub search: String,
+ pub max_result_count: Option<u32>,
+ pub file: Option<String>,
+}
+
/// Methods that are supported by the Language Service in the compiler isolate.
#[derive(Debug)]
-pub enum RequestMethod {
+enum RequestMethod {
/// Configure the compilation settings for the server.
Configure(TsConfig),
/// Get rename locations at a given position.
@@ -3198,11 +3583,7 @@ pub enum RequestMethod {
/// Get implementation information for a specific position.
GetImplementation((ModuleSpecifier, u32)),
/// Get "navigate to" items, which are converted to workspace symbols
- GetNavigateToItems {
- search: String,
- max_result_count: Option<u32>,
- file: Option<String>,
- },
+ GetNavigateToItems(GetNavigateToItemsArgs),
/// Get a "navigation tree" for a specifier.
GetNavigationTree(ModuleSpecifier),
/// Get outlining spans for a specifier.
@@ -3356,11 +3737,11 @@ impl RequestMethod {
"specifier": state.denormalize_specifier(specifier),
"position": position,
}),
- RequestMethod::GetNavigateToItems {
+ RequestMethod::GetNavigateToItems(GetNavigateToItemsArgs {
search,
max_result_count,
file,
- } => json!({
+ }) => json!({
"id": id,
"method": "getNavigateToItems",
"search": search,
@@ -3470,7 +3851,7 @@ impl RequestMethod {
}
/// Send a request into a runtime and return the JSON value of the response.
-pub fn request(
+fn request(
runtime: &mut JsRuntime,
state_snapshot: Arc<StateSnapshot>,
method: RequestMethod,
diff --git a/cli/npm/cache.rs b/cli/npm/cache.rs
index cda40fd17..aba6c0cca 100644
--- a/cli/npm/cache.rs
+++ b/cli/npm/cache.rs
@@ -20,7 +20,6 @@ use deno_semver::Version;
use once_cell::sync::Lazy;
use crate::args::CacheSetting;
-use crate::cache::DenoDir;
use crate::http_util::HttpClient;
use crate::util::fs::canonicalize_path;
use crate::util::fs::hard_link_dir_recursive;
@@ -120,20 +119,6 @@ pub struct ReadonlyNpmCache {
root_dir_url: Url,
}
-// todo(dsherret): implementing Default for this is error prone because someone
-// might accidentally use the default implementation instead of getting the
-// correct location of the deno dir, which might be provided via a CLI argument.
-// That said, the rest of the LSP code does this at the moment and so this code
-// copies that.
-impl Default for ReadonlyNpmCache {
- fn default() -> Self {
- // This only gets used when creating the tsc runtime and for testing, and so
- // it shouldn't ever actually access the DenoDir, so it doesn't support a
- // custom root.
- Self::new(DenoDir::new(None).unwrap().npm_folder_path())
- }
-}
-
impl ReadonlyNpmCache {
pub fn new(root_dir: PathBuf) -> Self {
fn try_get_canonicalized_root_dir(