@@ -228,18 +228,21 @@ pub struct TsResponseImportMapper<'a> {
228228 documents : & ' a Documents ,
229229 maybe_import_map : Option < & ' a ImportMap > ,
230230 resolver : & ' a LspResolver ,
231+ file_referrer : ModuleSpecifier ,
231232}
232233
233234impl < ' a > TsResponseImportMapper < ' a > {
234235 pub fn new (
235236 documents : & ' a Documents ,
236237 maybe_import_map : Option < & ' a ImportMap > ,
237238 resolver : & ' a LspResolver ,
239+ file_referrer : & ModuleSpecifier ,
238240 ) -> Self {
239241 Self {
240242 documents,
241243 maybe_import_map,
242244 resolver,
245+ file_referrer : file_referrer. clone ( ) ,
243246 }
244247 }
245248
@@ -260,8 +263,6 @@ impl<'a> TsResponseImportMapper<'a> {
260263 }
261264 }
262265
263- let file_referrer = self . documents . get_file_referrer ( referrer) ;
264-
265266 if let Some ( jsr_path) = specifier. as_str ( ) . strip_prefix ( jsr_url ( ) . as_str ( ) )
266267 {
267268 let mut segments = jsr_path. split ( '/' ) ;
@@ -276,7 +277,7 @@ impl<'a> TsResponseImportMapper<'a> {
276277 let export = self . resolver . jsr_lookup_export_for_path (
277278 & nv,
278279 & path,
279- file_referrer . as_deref ( ) ,
280+ Some ( & self . file_referrer ) ,
280281 ) ?;
281282 let sub_path = ( export != "." ) . then_some ( export) ;
282283 let mut req = None ;
@@ -302,7 +303,7 @@ impl<'a> TsResponseImportMapper<'a> {
302303 req = req. or_else ( || {
303304 self
304305 . resolver
305- . jsr_lookup_req_for_nv ( & nv, file_referrer . as_deref ( ) )
306+ . jsr_lookup_req_for_nv ( & nv, Some ( & self . file_referrer ) )
306307 } ) ;
307308 let spec_str = if let Some ( req) = req {
308309 let req_ref = PackageReqReference { req, sub_path } ;
@@ -332,7 +333,7 @@ impl<'a> TsResponseImportMapper<'a> {
332333
333334 if let Some ( npm_resolver) = self
334335 . resolver
335- . maybe_managed_npm_resolver ( file_referrer . as_deref ( ) )
336+ . maybe_managed_npm_resolver ( Some ( & self . file_referrer ) )
336337 {
337338 if npm_resolver. in_npm_package ( specifier) {
338339 if let Ok ( Some ( pkg_id) ) =
@@ -468,6 +469,26 @@ impl<'a> TsResponseImportMapper<'a> {
468469 }
469470 None
470471 }
472+
473+ pub fn is_valid_import (
474+ & self ,
475+ specifier_text : & str ,
476+ referrer : & ModuleSpecifier ,
477+ ) -> bool {
478+ self
479+ . resolver
480+ . as_graph_resolver ( Some ( & self . file_referrer ) )
481+ . resolve (
482+ specifier_text,
483+ & deno_graph:: Range {
484+ specifier : referrer. clone ( ) ,
485+ start : deno_graph:: Position :: zeroed ( ) ,
486+ end : deno_graph:: Position :: zeroed ( ) ,
487+ } ,
488+ deno_graph:: source:: ResolutionMode :: Types ,
489+ )
490+ . is_ok ( )
491+ }
471492}
472493
473494fn try_reverse_map_package_json_exports (
@@ -580,7 +601,7 @@ fn fix_ts_import_action(
580601 referrer : & ModuleSpecifier ,
581602 action : & tsc:: CodeFixAction ,
582603 import_mapper : & TsResponseImportMapper ,
583- ) -> Result < tsc:: CodeFixAction , AnyError > {
604+ ) -> Result < Option < tsc:: CodeFixAction > , AnyError > {
584605 if matches ! (
585606 action. fix_name. as_str( ) ,
586607 "import" | "fixMissingFunctionDeclaration"
@@ -623,19 +644,21 @@ fn fix_ts_import_action(
623644 } )
624645 . collect ( ) ;
625646
626- return Ok ( tsc:: CodeFixAction {
647+ return Ok ( Some ( tsc:: CodeFixAction {
627648 description,
628649 changes,
629650 commands : None ,
630651 fix_name : action. fix_name . clone ( ) ,
631652 fix_id : None ,
632653 fix_all_description : None ,
633- } ) ;
654+ } ) ) ;
655+ } else if !import_mapper. is_valid_import ( specifier, referrer) {
656+ return Ok ( None ) ;
634657 }
635658 }
636659 }
637660
638- Ok ( action. clone ( ) )
661+ Ok ( Some ( action. clone ( ) ) )
639662}
640663
641664/// Determines if two TypeScript diagnostic codes are effectively equivalent.
@@ -976,11 +999,14 @@ impl CodeActionCollection {
976999 "The action returned from TypeScript is unsupported." ,
9771000 ) ) ;
9781001 }
979- let action = fix_ts_import_action (
1002+ let Some ( action) = fix_ts_import_action (
9801003 specifier,
9811004 action,
9821005 & language_server. get_ts_response_import_mapper ( specifier) ,
983- ) ?;
1006+ ) ?
1007+ else {
1008+ return Ok ( ( ) ) ;
1009+ } ;
9841010 let edit = ts_changes_to_edit ( & action. changes , language_server) ?;
9851011 let code_action = lsp:: CodeAction {
9861012 title : action. description . clone ( ) ,
0 commit comments