summaryrefslogtreecommitdiff
path: root/cli/lsp/tsc.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/lsp/tsc.rs')
-rw-r--r--cli/lsp/tsc.rs92
1 files changed, 67 insertions, 25 deletions
diff --git a/cli/lsp/tsc.rs b/cli/lsp/tsc.rs
index 48dcb7964..fc7ff5794 100644
--- a/cli/lsp/tsc.rs
+++ b/cli/lsp/tsc.rs
@@ -3417,9 +3417,18 @@ fn parse_code_actions(
additional_text_edits.extend(change.text_changes.iter().map(|tc| {
let mut text_edit = tc.as_text_edit(asset_or_doc.line_index());
if let Some(specifier_rewrite) = &data.specifier_rewrite {
- text_edit.new_text = text_edit
- .new_text
- .replace(&specifier_rewrite.0, &specifier_rewrite.1);
+ text_edit.new_text = text_edit.new_text.replace(
+ &specifier_rewrite.old_specifier,
+ &specifier_rewrite.new_specifier,
+ );
+ if let Some(deno_types_specifier) =
+ &specifier_rewrite.new_deno_types_specifier
+ {
+ text_edit.new_text = format!(
+ "// @deno-types=\"{}\"\n{}",
+ deno_types_specifier, &text_edit.new_text
+ );
+ }
}
text_edit
}));
@@ -3578,17 +3587,23 @@ impl CompletionEntryDetails {
let mut text_edit = original_item.text_edit.clone();
if let Some(specifier_rewrite) = &data.specifier_rewrite {
if let Some(text_edit) = &mut text_edit {
- match text_edit {
- lsp::CompletionTextEdit::Edit(text_edit) => {
- text_edit.new_text = text_edit
- .new_text
- .replace(&specifier_rewrite.0, &specifier_rewrite.1);
- }
+ let new_text = match text_edit {
+ lsp::CompletionTextEdit::Edit(text_edit) => &mut text_edit.new_text,
lsp::CompletionTextEdit::InsertAndReplace(insert_replace_edit) => {
- insert_replace_edit.new_text = insert_replace_edit
- .new_text
- .replace(&specifier_rewrite.0, &specifier_rewrite.1);
+ &mut insert_replace_edit.new_text
}
+ };
+ *new_text = new_text.replace(
+ &specifier_rewrite.old_specifier,
+ &specifier_rewrite.new_specifier,
+ );
+ if let Some(deno_types_specifier) =
+ &specifier_rewrite.new_deno_types_specifier
+ {
+ *new_text = format!(
+ "// @deno-types=\"{}\"\n{}",
+ deno_types_specifier, new_text
+ );
}
}
}
@@ -3693,6 +3708,13 @@ impl CompletionInfo {
}
}
+#[derive(Debug, Clone, Deserialize, Serialize)]
+pub struct CompletionSpecifierRewrite {
+ old_specifier: String,
+ new_specifier: String,
+ new_deno_types_specifier: Option<String>,
+}
+
#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CompletionItemData {
@@ -3705,7 +3727,7 @@ pub struct CompletionItemData {
/// be rewritten by replacing the first string with the second. Intended for
/// auto-import specifiers to be reverse-import-mapped.
#[serde(skip_serializing_if = "Option::is_none")]
- pub specifier_rewrite: Option<(String, String)>,
+ pub specifier_rewrite: Option<CompletionSpecifierRewrite>,
#[serde(skip_serializing_if = "Option::is_none")]
pub data: Option<Value>,
pub use_code_snippet: bool,
@@ -3927,20 +3949,40 @@ impl CompletionEntry {
if let Some(source) = &self.source {
let mut display_source = source.clone();
if let Some(import_data) = &self.auto_import_data {
- if let Some(new_module_specifier) = language_server
- .get_ts_response_import_mapper(specifier)
+ let import_mapper =
+ language_server.get_ts_response_import_mapper(specifier);
+ if let Some(mut new_specifier) = import_mapper
.check_specifier(&import_data.normalized, specifier)
.or_else(|| relative_specifier(specifier, &import_data.normalized))
{
- if new_module_specifier.contains("/node_modules/") {
+ if new_specifier.contains("/node_modules/") {
return None;
}
- display_source.clone_from(&new_module_specifier);
- if new_module_specifier != import_data.raw.module_specifier {
- specifier_rewrite = Some((
- import_data.raw.module_specifier.clone(),
- new_module_specifier,
- ));
+ let mut new_deno_types_specifier = None;
+ if let Some(code_specifier) = language_server
+ .resolver
+ .deno_types_to_code_resolution(
+ &import_data.normalized,
+ Some(specifier),
+ )
+ .and_then(|s| {
+ import_mapper
+ .check_specifier(&s, specifier)
+ .or_else(|| relative_specifier(specifier, &s))
+ })
+ {
+ new_deno_types_specifier =
+ Some(std::mem::replace(&mut new_specifier, code_specifier));
+ }
+ display_source.clone_from(&new_specifier);
+ if new_specifier != import_data.raw.module_specifier
+ || new_deno_types_specifier.is_some()
+ {
+ specifier_rewrite = Some(CompletionSpecifierRewrite {
+ old_specifier: import_data.raw.module_specifier.clone(),
+ new_specifier,
+ new_deno_types_specifier,
+ });
}
} else if source.starts_with(jsr_url().as_str()) {
return None;
@@ -4246,9 +4288,7 @@ impl TscSpecifierMap {
return specifier.to_string();
}
let mut specifier = original.to_string();
- if specifier.contains("/node_modules/.deno/")
- && !specifier.contains("/node_modules/@types/node/")
- {
+ if !specifier.contains("/node_modules/@types/node/") {
// The ts server doesn't give completions from files in
// `node_modules/.deno/`. We work around it like this.
specifier = specifier.replace("/node_modules/", "/$node_modules/");
@@ -4415,6 +4455,8 @@ fn op_load<'s>(
})
};
+ lsp_warn!("op_load {} {}", &specifier, maybe_load_response.is_some());
+
let serialized = serde_v8::to_v8(scope, maybe_load_response)?;
state.performance.measure(mark);