@@ -205,13 +205,15 @@ namespace ts {
205
205
}
206
206
207
207
export function getPreEmitDiagnostics ( program : Program , sourceFile ?: SourceFile , cancellationToken ?: CancellationToken ) : Diagnostic [ ] {
208
- let diagnostics = program . getOptionsDiagnostics ( cancellationToken ) . concat (
209
- program . getSyntacticDiagnostics ( sourceFile , cancellationToken ) ,
210
- program . getGlobalDiagnostics ( cancellationToken ) ,
211
- program . getSemanticDiagnostics ( sourceFile , cancellationToken ) ) ;
208
+ const diagnostics = [
209
+ ...program . getOptionsDiagnostics ( cancellationToken ) ,
210
+ ...program . getSyntacticDiagnostics ( sourceFile , cancellationToken ) ,
211
+ ...program . getGlobalDiagnostics ( cancellationToken ) ,
212
+ ...program . getSemanticDiagnostics ( sourceFile , cancellationToken )
213
+ ] ;
212
214
213
215
if ( program . getCompilerOptions ( ) . declaration ) {
214
- diagnostics = diagnostics . concat ( program . getDeclarationDiagnostics ( sourceFile , cancellationToken ) ) ;
216
+ addRange ( diagnostics , program . getDeclarationDiagnostics ( sourceFile , cancellationToken ) ) ;
215
217
}
216
218
217
219
return sortAndDeduplicateDiagnostics ( diagnostics ) ;
@@ -223,7 +225,7 @@ namespace ts {
223
225
getNewLine ( ) : string ;
224
226
}
225
227
226
- export function formatDiagnostics ( diagnostics : Diagnostic [ ] , host : FormatDiagnosticsHost ) : string {
228
+ export function formatDiagnostics ( diagnostics : ReadonlyArray < Diagnostic > , host : FormatDiagnosticsHost ) : string {
227
229
let output = "" ;
228
230
229
231
for ( const diagnostic of diagnostics ) {
@@ -399,7 +401,7 @@ namespace ts {
399
401
* @param oldProgram - Reuses an old program structure.
400
402
* @returns A 'Program' object.
401
403
*/
402
- export function createProgram ( rootNames : string [ ] , options : CompilerOptions , host ?: CompilerHost , oldProgram ?: Program ) : Program {
404
+ export function createProgram ( rootNames : ReadonlyArray < string > , options : CompilerOptions , host ?: CompilerHost , oldProgram ?: Program ) : Program {
403
405
let program : Program ;
404
406
let files : SourceFile [ ] = [ ] ;
405
407
let commonSourceDirectory : string ;
@@ -888,7 +890,7 @@ namespace ts {
888
890
for ( const { oldFile : oldSourceFile , newFile : newSourceFile } of modifiedSourceFiles ) {
889
891
const newSourceFilePath = getNormalizedAbsolutePath ( newSourceFile . fileName , currentDirectory ) ;
890
892
if ( resolveModuleNamesWorker ) {
891
- const moduleNames = map ( concatenate ( newSourceFile . imports , newSourceFile . moduleAugmentations ) , getTextOfLiteral ) ;
893
+ const moduleNames = getModuleNames ( newSourceFile ) ;
892
894
const oldProgramState = { program : oldProgram , file : oldSourceFile , modifiedFilePaths } ;
893
895
const resolutions = resolveModuleNamesReusingOldState ( moduleNames , newSourceFilePath , newSourceFile , oldProgramState ) ;
894
896
// ensure that module resolution results are still correct
@@ -996,7 +998,7 @@ namespace ts {
996
998
}
997
999
998
1000
function emitWorker ( program : Program , sourceFile : SourceFile , writeFileCallback : WriteFileCallback , cancellationToken : CancellationToken , emitOnlyDtsFiles ?: boolean , customTransformers ?: CustomTransformers ) : EmitResult {
999
- let declarationDiagnostics : Diagnostic [ ] = [ ] ;
1001
+ let declarationDiagnostics : ReadonlyArray < Diagnostic > = [ ] ;
1000
1002
1001
1003
if ( options . noEmit ) {
1002
1004
return { diagnostics : declarationDiagnostics , sourceMaps : undefined , emittedFiles : undefined , emitSkipped : true } ;
@@ -1006,10 +1008,12 @@ namespace ts {
1006
1008
// immediately bail out. Note that we pass 'undefined' for 'sourceFile' so that we
1007
1009
// get any preEmit diagnostics, not just the ones
1008
1010
if ( options . noEmitOnError ) {
1009
- const diagnostics = program . getOptionsDiagnostics ( cancellationToken ) . concat (
1010
- program . getSyntacticDiagnostics ( sourceFile , cancellationToken ) ,
1011
- program . getGlobalDiagnostics ( cancellationToken ) ,
1012
- program . getSemanticDiagnostics ( sourceFile , cancellationToken ) ) ;
1011
+ const diagnostics = [
1012
+ ...program . getOptionsDiagnostics ( cancellationToken ) ,
1013
+ ...program . getSyntacticDiagnostics ( sourceFile , cancellationToken ) ,
1014
+ ...program . getGlobalDiagnostics ( cancellationToken ) ,
1015
+ ...program . getSemanticDiagnostics ( sourceFile , cancellationToken )
1016
+ ] ;
1013
1017
1014
1018
if ( diagnostics . length === 0 && program . getCompilerOptions ( ) . declaration ) {
1015
1019
declarationDiagnostics = program . getDeclarationDiagnostics ( /*sourceFile*/ undefined , cancellationToken ) ;
@@ -1060,8 +1064,8 @@ namespace ts {
1060
1064
1061
1065
function getDiagnosticsHelper (
1062
1066
sourceFile : SourceFile ,
1063
- getDiagnostics : ( sourceFile : SourceFile , cancellationToken : CancellationToken ) => Diagnostic [ ] ,
1064
- cancellationToken : CancellationToken ) : Diagnostic [ ] {
1067
+ getDiagnostics : ( sourceFile : SourceFile , cancellationToken : CancellationToken ) => ReadonlyArray < Diagnostic > ,
1068
+ cancellationToken : CancellationToken ) : ReadonlyArray < Diagnostic > {
1065
1069
if ( sourceFile ) {
1066
1070
return getDiagnostics ( sourceFile , cancellationToken ) ;
1067
1071
}
@@ -1073,15 +1077,15 @@ namespace ts {
1073
1077
} ) ) ;
1074
1078
}
1075
1079
1076
- function getSyntacticDiagnostics ( sourceFile : SourceFile , cancellationToken : CancellationToken ) : Diagnostic [ ] {
1080
+ function getSyntacticDiagnostics ( sourceFile : SourceFile , cancellationToken : CancellationToken ) : ReadonlyArray < Diagnostic > {
1077
1081
return getDiagnosticsHelper ( sourceFile , getSyntacticDiagnosticsForFile , cancellationToken ) ;
1078
1082
}
1079
1083
1080
- function getSemanticDiagnostics ( sourceFile : SourceFile , cancellationToken : CancellationToken ) : Diagnostic [ ] {
1084
+ function getSemanticDiagnostics ( sourceFile : SourceFile , cancellationToken : CancellationToken ) : ReadonlyArray < Diagnostic > {
1081
1085
return getDiagnosticsHelper ( sourceFile , getSemanticDiagnosticsForFile , cancellationToken ) ;
1082
1086
}
1083
1087
1084
- function getDeclarationDiagnostics ( sourceFile : SourceFile , cancellationToken : CancellationToken ) : Diagnostic [ ] {
1088
+ function getDeclarationDiagnostics ( sourceFile : SourceFile , cancellationToken : CancellationToken ) : ReadonlyArray < Diagnostic > {
1085
1089
const options = program . getCompilerOptions ( ) ;
1086
1090
// collect diagnostics from the program only once if either no source file was specified or out/outFile is set (bundled emit)
1087
1091
if ( ! sourceFile || options . out || options . outFile ) {
@@ -1092,7 +1096,7 @@ namespace ts {
1092
1096
}
1093
1097
}
1094
1098
1095
- function getSyntacticDiagnosticsForFile ( sourceFile : SourceFile ) : Diagnostic [ ] {
1099
+ function getSyntacticDiagnosticsForFile ( sourceFile : SourceFile ) : ReadonlyArray < Diagnostic > {
1096
1100
// For JavaScript files, we report semantic errors for using TypeScript-only
1097
1101
// constructs from within a JavaScript file as syntactic errors.
1098
1102
if ( isSourceFileJavaScript ( sourceFile ) ) {
@@ -1430,12 +1434,10 @@ namespace ts {
1430
1434
return a . fileName === b . fileName ;
1431
1435
}
1432
1436
1433
- function moduleNameIsEqualTo ( a : LiteralExpression , b : LiteralExpression ) : boolean {
1434
- return a . text === b . text ;
1435
- }
1436
-
1437
- function getTextOfLiteral ( literal : LiteralExpression ) : string {
1438
- return literal . text ;
1437
+ function moduleNameIsEqualTo ( a : StringLiteral | Identifier , b : StringLiteral | Identifier ) : boolean {
1438
+ return a . kind === SyntaxKind . StringLiteral
1439
+ ? b . kind === SyntaxKind . StringLiteral && a . text === b . text
1440
+ : b . kind === SyntaxKind . Identifier && a . escapedText === b . escapedText ;
1439
1441
}
1440
1442
1441
1443
function collectExternalModuleReferences ( file : SourceFile ) : void {
@@ -1448,7 +1450,7 @@ namespace ts {
1448
1450
1449
1451
// file.imports may not be undefined if there exists dynamic import
1450
1452
let imports : StringLiteral [ ] ;
1451
- let moduleAugmentations : StringLiteral [ ] ;
1453
+ let moduleAugmentations : Array < StringLiteral | Identifier > ;
1452
1454
let ambientModules : string [ ] ;
1453
1455
1454
1456
// If we are importing helpers, we need to add a synthetic reference to resolve the
@@ -1477,7 +1479,7 @@ namespace ts {
1477
1479
1478
1480
return ;
1479
1481
1480
- function collectModuleReferences ( node : Node , inAmbientModule : boolean ) : void {
1482
+ function collectModuleReferences ( node : Statement , inAmbientModule : boolean ) : void {
1481
1483
switch ( node . kind ) {
1482
1484
case SyntaxKind . ImportDeclaration :
1483
1485
case SyntaxKind . ImportEqualsDeclaration :
@@ -1499,8 +1501,8 @@ namespace ts {
1499
1501
break ;
1500
1502
case SyntaxKind . ModuleDeclaration :
1501
1503
if ( isAmbientModule ( < ModuleDeclaration > node ) && ( inAmbientModule || hasModifier ( node , ModifierFlags . Ambient ) || file . isDeclarationFile ) ) {
1502
- const moduleName = < StringLiteral > ( < ModuleDeclaration > node ) . name ; // TODO: GH#17347
1503
- const nameText = ts . getTextOfIdentifierOrLiteral ( moduleName ) ;
1504
+ const moduleName = ( < ModuleDeclaration > node ) . name ;
1505
+ const nameText = getTextOfIdentifierOrLiteral ( moduleName ) ;
1504
1506
// Ambient module declarations can be interpreted as augmentations for some existing external modules.
1505
1507
// This will happen in two cases:
1506
1508
// - if current file is external module then module augmentation is a ambient module declaration defined in the top level scope
@@ -1817,8 +1819,7 @@ namespace ts {
1817
1819
collectExternalModuleReferences ( file ) ;
1818
1820
if ( file . imports . length || file . moduleAugmentations . length ) {
1819
1821
// Because global augmentation doesn't have string literal name, we can check for global augmentation as such.
1820
- const nonGlobalAugmentation = filter ( file . moduleAugmentations , ( moduleAugmentation ) => moduleAugmentation . kind === SyntaxKind . StringLiteral ) ;
1821
- const moduleNames = map ( concatenate ( file . imports , nonGlobalAugmentation ) , getTextOfLiteral ) ;
1822
+ const moduleNames = getModuleNames ( file ) ;
1822
1823
const oldProgramState = { program : oldProgram , file, modifiedFilePaths } ;
1823
1824
const resolutions = resolveModuleNamesReusingOldState ( moduleNames , getNormalizedAbsolutePath ( file . fileName , currentDirectory ) , file , oldProgramState ) ;
1824
1825
Debug . assert ( resolutions . length === moduleNames . length ) ;
@@ -2229,4 +2230,15 @@ namespace ts {
2229
2230
Debug . assert ( names . every ( name => name !== undefined ) , "A name is undefined." , ( ) => JSON . stringify ( names ) ) ;
2230
2231
return names ;
2231
2232
}
2233
+
2234
+ function getModuleNames ( { imports, moduleAugmentations } : SourceFile ) : string [ ] {
2235
+ const res = imports . map ( i => i . text ) ;
2236
+ for ( const aug of moduleAugmentations ) {
2237
+ if ( aug . kind === SyntaxKind . StringLiteral ) {
2238
+ res . push ( aug . text ) ;
2239
+ }
2240
+ // Do nothing if it's an Identifier; we don't need to do module resolution for `declare global`.
2241
+ }
2242
+ return res ;
2243
+ }
2232
2244
}
0 commit comments