mirror of
https://github.com/denoland/deno.git
synced 2024-12-01 16:51:13 -05:00
refactor(lsp): make RequestMethod
private (#19114)
This commit is contained in:
parent
12ba2d311b
commit
995b1e683f
5 changed files with 628 additions and 382 deletions
|
@ -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?;
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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(¶ms));
|
||||
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(¶ms));
|
||||
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(¶ms));
|
||||
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(¶ms));
|
||||
|
||||
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(¶ms));
|
||||
let asset_or_doc = self.get_asset_or_document(&specifier)?;
|
||||
let line_index = asset_or_doc.line_index();
|
||||
let range = tsc::TextSpan::from_range(¶ms.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(¶ms.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()
|
||||
|
|
443
cli/lsp/tsc.rs
443
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,
|
||||
|
|
|
@ -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(
|
||||
|
|
Loading…
Reference in a new issue