@@ -31,6 +31,7 @@ use crate::tsc::ResolveArgs;
31
31
use crate :: util:: path:: relative_specifier;
32
32
use crate :: util:: path:: specifier_to_file_path;
33
33
34
+ use deno_ast:: MediaType ;
34
35
use deno_core:: anyhow:: anyhow;
35
36
use deno_core:: error:: custom_error;
36
37
use deno_core:: error:: AnyError ;
@@ -3167,7 +3168,8 @@ struct State {
3167
3168
performance : Arc < Performance > ,
3168
3169
response : Option < Response > ,
3169
3170
state_snapshot : Arc < StateSnapshot > ,
3170
- specifiers : HashMap < String , String > ,
3171
+ normalized_specifiers : HashMap < String , ModuleSpecifier > ,
3172
+ denormalized_specifiers : HashMap < ModuleSpecifier , String > ,
3171
3173
token : CancellationToken ,
3172
3174
}
3173
3175
@@ -3181,36 +3183,55 @@ impl State {
3181
3183
performance,
3182
3184
response : None ,
3183
3185
state_snapshot,
3184
- specifiers : HashMap :: default ( ) ,
3186
+ normalized_specifiers : HashMap :: default ( ) ,
3187
+ denormalized_specifiers : HashMap :: default ( ) ,
3185
3188
token : Default :: default ( ) ,
3186
3189
}
3187
3190
}
3188
3191
3189
- /// If a normalized version of the specifier has been stored for tsc, this
3190
- /// will "restore" it for communicating back to the tsc language server,
3191
- /// otherwise it will just convert the specifier to a string.
3192
- fn denormalize_specifier ( & self , specifier : & ModuleSpecifier ) -> String {
3193
- let specifier_str = specifier. to_string ( ) ;
3194
- self
3195
- . specifiers
3196
- . get ( & specifier_str)
3197
- . unwrap_or ( & specifier_str)
3198
- . to_string ( )
3192
+ /// Convert the specifier to one compatible with tsc. Cache the resulting
3193
+ /// mapping in case it needs to be reversed.
3194
+ fn denormalize_specifier ( & mut self , specifier : & ModuleSpecifier ) -> String {
3195
+ let original = specifier;
3196
+ if let Some ( specifier) = self . denormalized_specifiers . get ( original) {
3197
+ return specifier. to_string ( ) ;
3198
+ }
3199
+ let mut specifier = original. to_string ( ) ;
3200
+ let media_type = MediaType :: from_specifier ( original) ;
3201
+ // If the URL-inferred media type doesn't correspond to tsc's path-inferred
3202
+ // media type, force it to be the same by appending an extension.
3203
+ if MediaType :: from_path ( Path :: new ( specifier. as_str ( ) ) ) != media_type {
3204
+ specifier += media_type. as_ts_extension ( ) ;
3205
+ }
3206
+ if specifier != original. as_str ( ) {
3207
+ self
3208
+ . normalized_specifiers
3209
+ . insert ( specifier. clone ( ) , original. clone ( ) ) ;
3210
+ }
3211
+ specifier
3199
3212
}
3200
3213
3201
- /// In certain situations, tsc can request "invalid" specifiers and this will
3202
- /// normalize and memoize the specifier .
3214
+ /// Convert the specifier from one compatible with tsc. Cache the resulting
3215
+ /// mapping in case it needs to be reversed .
3203
3216
fn normalize_specifier < S : AsRef < str > > (
3204
3217
& mut self ,
3205
3218
specifier : S ,
3206
3219
) -> Result < ModuleSpecifier , AnyError > {
3207
- let specifier_str = specifier. as_ref ( ) . replace ( ".d.ts.d.ts" , ".d.ts" ) ;
3208
- if specifier_str != specifier. as_ref ( ) {
3220
+ let original = specifier. as_ref ( ) ;
3221
+ if let Some ( specifier) = self . normalized_specifiers . get ( original) {
3222
+ return Ok ( specifier. clone ( ) ) ;
3223
+ }
3224
+ let specifier_str = original. replace ( ".d.ts.d.ts" , ".d.ts" ) ;
3225
+ let specifier = match ModuleSpecifier :: parse ( & specifier_str) {
3226
+ Ok ( s) => s,
3227
+ Err ( err) => return Err ( err. into ( ) ) ,
3228
+ } ;
3229
+ if specifier. as_str ( ) != original {
3209
3230
self
3210
- . specifiers
3211
- . insert ( specifier_str . clone ( ) , specifier . as_ref ( ) . to_string ( ) ) ;
3231
+ . denormalized_specifiers
3232
+ . insert ( specifier . clone ( ) , original . to_string ( ) ) ;
3212
3233
}
3213
- ModuleSpecifier :: parse ( & specifier_str ) . map_err ( |err| err . into ( ) )
3234
+ Ok ( specifier )
3214
3235
}
3215
3236
3216
3237
fn get_asset_or_document (
@@ -3324,7 +3345,12 @@ fn op_resolve(
3324
3345
resolved
3325
3346
. into_iter ( )
3326
3347
. map ( |o| {
3327
- o. map ( |( s, mt) | ( s. to_string ( ) , mt. as_ts_extension ( ) . to_string ( ) ) )
3348
+ o. map ( |( s, mt) | {
3349
+ (
3350
+ state. denormalize_specifier ( & s) ,
3351
+ mt. as_ts_extension ( ) . to_string ( ) ,
3352
+ )
3353
+ } )
3328
3354
} )
3329
3355
. collect ( ) ,
3330
3356
)
@@ -3861,7 +3887,7 @@ enum RequestMethod {
3861
3887
}
3862
3888
3863
3889
impl RequestMethod {
3864
- fn to_value ( & self , state : & State , id : usize ) -> Value {
3890
+ fn to_value ( & self , state : & mut State , id : usize ) -> Value {
3865
3891
match self {
3866
3892
RequestMethod :: Configure ( config) => json ! ( {
3867
3893
"id" : id,
0 commit comments