@@ -12,6 +12,7 @@ import { sendSync } from "./dispatch";
12
12
import * as flatbuffers from "./flatbuffers" ;
13
13
import * as os from "./os" ;
14
14
import { TextDecoder , TextEncoder } from "./text_encoding" ;
15
+ import { getMappedModuleName , parseTypeDirectives } from "./type_directives" ;
15
16
import { assert , notImplemented } from "./util" ;
16
17
import * as util from "./util" ;
17
18
import { window } from "./window" ;
@@ -112,6 +113,7 @@ interface SourceFile {
112
113
filename : string | undefined ;
113
114
mediaType : msg . MediaType ;
114
115
sourceCode : string | undefined ;
116
+ typeDirectives ?: Record < string , string > ;
115
117
}
116
118
117
119
interface EmitResult {
@@ -121,7 +123,7 @@ interface EmitResult {
121
123
122
124
/** Ops to Rust to resolve and fetch a modules meta data. */
123
125
function fetchSourceFile ( specifier : string , referrer : string ) : SourceFile {
124
- util . log ( "compiler. fetchSourceFile" , { specifier, referrer } ) ;
126
+ util . log ( "fetchSourceFile" , { specifier, referrer } ) ;
125
127
// Send FetchSourceFile message
126
128
const builder = flatbuffers . createBuilder ( ) ;
127
129
const specifier_ = builder . createString ( specifier ) ;
@@ -148,7 +150,8 @@ function fetchSourceFile(specifier: string, referrer: string): SourceFile {
148
150
moduleName : fetchSourceFileRes . moduleName ( ) || undefined ,
149
151
filename : fetchSourceFileRes . filename ( ) || undefined ,
150
152
mediaType : fetchSourceFileRes . mediaType ( ) ,
151
- sourceCode
153
+ sourceCode,
154
+ typeDirectives : parseTypeDirectives ( sourceCode )
152
155
} ;
153
156
}
154
157
@@ -170,7 +173,7 @@ function humanFileSize(bytes: number): string {
170
173
171
174
/** Ops to rest for caching source map and compiled js */
172
175
function cache ( extension : string , moduleId : string , contents : string ) : void {
173
- util . log ( "compiler. cache" , moduleId ) ;
176
+ util . log ( "cache" , extension , moduleId ) ;
174
177
const builder = flatbuffers . createBuilder ( ) ;
175
178
const extension_ = builder . createString ( extension ) ;
176
179
const moduleId_ = builder . createString ( moduleId ) ;
@@ -191,7 +194,7 @@ const encoder = new TextEncoder();
191
194
function emitBundle ( fileName : string , data : string ) : void {
192
195
// For internal purposes, when trying to emit to `$deno$` just no-op
193
196
if ( fileName . startsWith ( "$deno$" ) ) {
194
- console . warn ( "skipping compiler. emitBundle" , fileName ) ;
197
+ console . warn ( "skipping emitBundle" , fileName ) ;
195
198
return ;
196
199
}
197
200
const encodedData = encoder . encode ( data ) ;
@@ -219,7 +222,7 @@ function getExtension(
219
222
}
220
223
221
224
class Host implements ts . CompilerHost {
222
- extensionCache : Record < string , ts . Extension > = { } ;
225
+ private _extensionCache : Record < string , ts . Extension > = { } ;
223
226
224
227
private readonly _options : ts . CompilerOptions = {
225
228
allowJs : true ,
@@ -234,23 +237,37 @@ class Host implements ts.CompilerHost {
234
237
target : ts . ScriptTarget . ESNext
235
238
} ;
236
239
240
+ private _sourceFileCache : Record < string , SourceFile > = { } ;
241
+
237
242
private _resolveModule ( specifier : string , referrer : string ) : SourceFile {
243
+ util . log ( "host._resolveModule" , { specifier, referrer } ) ;
238
244
// Handle built-in assets specially.
239
245
if ( specifier . startsWith ( ASSETS ) ) {
240
246
const moduleName = specifier . split ( "/" ) . pop ( ) ! ;
247
+ if ( moduleName in this . _sourceFileCache ) {
248
+ return this . _sourceFileCache [ moduleName ] ;
249
+ }
241
250
const assetName = moduleName . includes ( "." )
242
251
? moduleName
243
252
: `${ moduleName } .d.ts` ;
244
253
assert ( assetName in assetSourceCode , `No such asset "${ assetName } "` ) ;
245
254
const sourceCode = assetSourceCode [ assetName ] ;
246
- return {
255
+ const sourceFile = {
247
256
moduleName,
248
257
filename : specifier ,
249
258
mediaType : msg . MediaType . TypeScript ,
250
259
sourceCode
251
260
} ;
261
+ this . _sourceFileCache [ moduleName ] = sourceFile ;
262
+ return sourceFile ;
263
+ }
264
+ const sourceFile = fetchSourceFile ( specifier , referrer ) ;
265
+ assert ( sourceFile . moduleName != null ) ;
266
+ const { moduleName } = sourceFile ;
267
+ if ( ! ( moduleName ! in this . _sourceFileCache ) ) {
268
+ this . _sourceFileCache [ moduleName ! ] = sourceFile ;
252
269
}
253
- return fetchSourceFile ( specifier , referrer ) ;
270
+ return sourceFile ;
254
271
}
255
272
256
273
/* Deno specific APIs */
@@ -279,7 +296,7 @@ class Host implements ts.CompilerHost {
279
296
* options which were ignored, or `undefined`.
280
297
*/
281
298
configure ( path : string , configurationText : string ) : ConfigureResponse {
282
- util . log ( "compile .configure" , path ) ;
299
+ util . log ( "host .configure" , path ) ;
283
300
const { config, error } = ts . parseConfigFileTextToJson (
284
301
path ,
285
302
configurationText
@@ -344,13 +361,17 @@ class Host implements ts.CompilerHost {
344
361
) : ts . SourceFile | undefined {
345
362
assert ( ! shouldCreateNewSourceFile ) ;
346
363
util . log ( "getSourceFile" , fileName ) ;
347
- const SourceFile = this . _resolveModule ( fileName , "." ) ;
348
- if ( ! SourceFile || ! SourceFile . sourceCode ) {
364
+ const sourceFile =
365
+ fileName in this . _sourceFileCache
366
+ ? this . _sourceFileCache [ fileName ]
367
+ : this . _resolveModule ( fileName , "." ) ;
368
+ assert ( sourceFile != null ) ;
369
+ if ( ! sourceFile . sourceCode ) {
349
370
return undefined ;
350
371
}
351
372
return ts . createSourceFile (
352
373
fileName ,
353
- SourceFile . sourceCode ,
374
+ sourceFile . sourceCode ,
354
375
languageVersion
355
376
) ;
356
377
}
@@ -364,26 +385,37 @@ class Host implements ts.CompilerHost {
364
385
containingFile : string
365
386
) : Array < ts . ResolvedModuleFull | undefined > {
366
387
util . log ( "resolveModuleNames()" , { moduleNames, containingFile } ) ;
388
+ const typeDirectives : Record < string , string > | undefined =
389
+ containingFile in this . _sourceFileCache
390
+ ? this . _sourceFileCache [ containingFile ] . typeDirectives
391
+ : undefined ;
367
392
return moduleNames . map (
368
393
( moduleName ) : ts . ResolvedModuleFull | undefined => {
369
- const SourceFile = this . _resolveModule ( moduleName , containingFile ) ;
370
- if ( SourceFile . moduleName ) {
371
- const resolvedFileName = SourceFile . moduleName ;
394
+ const mappedModuleName = getMappedModuleName (
395
+ moduleName ,
396
+ containingFile ,
397
+ typeDirectives
398
+ ) ;
399
+ const sourceFile = this . _resolveModule (
400
+ mappedModuleName ,
401
+ containingFile
402
+ ) ;
403
+ if ( sourceFile . moduleName ) {
404
+ const resolvedFileName = sourceFile . moduleName ;
372
405
// This flags to the compiler to not go looking to transpile functional
373
406
// code, anything that is in `/$asset$/` is just library code
374
407
const isExternalLibraryImport = moduleName . startsWith ( ASSETS ) ;
375
408
const extension = getExtension (
376
409
resolvedFileName ,
377
- SourceFile . mediaType
410
+ sourceFile . mediaType
378
411
) ;
379
- this . extensionCache [ resolvedFileName ] = extension ;
412
+ this . _extensionCache [ resolvedFileName ] = extension ;
380
413
381
- const r = {
414
+ return {
382
415
resolvedFileName,
383
416
isExternalLibraryImport,
384
417
extension
385
418
} ;
386
- return r ;
387
419
} else {
388
420
return undefined ;
389
421
}
@@ -409,7 +441,7 @@ class Host implements ts.CompilerHost {
409
441
} else {
410
442
assert ( sourceFiles != null && sourceFiles . length == 1 ) ;
411
443
const sourceFileName = sourceFiles ! [ 0 ] . fileName ;
412
- const maybeExtension = this . extensionCache [ sourceFileName ] ;
444
+ const maybeExtension = this . _extensionCache [ sourceFileName ] ;
413
445
414
446
if ( maybeExtension ) {
415
447
// NOTE: If it's a `.json` file we don't want to write it to disk.
0 commit comments