Skip to content

Commit f2b8e4b

Browse files
committed
Merge pull request #4743 from Microsoft/Port-4723
Port PR-4723 into release-1.6
2 parents 09309d8 + 4b5c2fe commit f2b8e4b

File tree

4 files changed

+67
-36
lines changed

4 files changed

+67
-36
lines changed

src/compiler/program.ts

Lines changed: 44 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,8 @@ namespace ts {
358358
export function createProgram(rootNames: string[], options: CompilerOptions, host?: CompilerHost, oldProgram?: Program): Program {
359359
let program: Program;
360360
let files: SourceFile[] = [];
361-
let diagnostics = createDiagnosticCollection();
361+
let fileProcessingDiagnostics = createDiagnosticCollection();
362+
let programDiagnostics = createDiagnosticCollection();
362363

363364
let commonSourceDirectory: string;
364365
let diagnosticsProducingTypeChecker: TypeChecker;
@@ -428,6 +429,7 @@ namespace ts {
428429
getIdentifierCount: () => getDiagnosticsProducingTypeChecker().getIdentifierCount(),
429430
getSymbolCount: () => getDiagnosticsProducingTypeChecker().getSymbolCount(),
430431
getTypeCount: () => getDiagnosticsProducingTypeChecker().getTypeCount(),
432+
getFileProcessingDiagnostics: () => fileProcessingDiagnostics
431433
};
432434
return program;
433435

@@ -460,6 +462,7 @@ namespace ts {
460462

461463
// check if program source files has changed in the way that can affect structure of the program
462464
let newSourceFiles: SourceFile[] = [];
465+
let modifiedSourceFiles: SourceFile[] = [];
463466
for (let oldSourceFile of oldProgram.getSourceFiles()) {
464467
let newSourceFile = host.getSourceFile(oldSourceFile.fileName, options.target);
465468
if (!newSourceFile) {
@@ -499,6 +502,7 @@ namespace ts {
499502
}
500503
// pass the cache of module resolutions from the old source file
501504
newSourceFile.resolvedModules = oldSourceFile.resolvedModules;
505+
modifiedSourceFiles.push(newSourceFile);
502506
}
503507
else {
504508
// file has no changes - use it as is
@@ -515,7 +519,11 @@ namespace ts {
515519
}
516520

517521
files = newSourceFiles;
522+
fileProcessingDiagnostics = oldProgram.getFileProcessingDiagnostics();
518523

524+
for (let modifiedFile of modifiedSourceFiles) {
525+
fileProcessingDiagnostics.reattachFileDiagnostics(modifiedFile);
526+
}
519527
oldProgram.structureIsReused = true;
520528

521529
return true;
@@ -645,9 +653,10 @@ namespace ts {
645653
Debug.assert(!!sourceFile.bindDiagnostics);
646654
let bindDiagnostics = sourceFile.bindDiagnostics;
647655
let checkDiagnostics = typeChecker.getDiagnostics(sourceFile, cancellationToken);
648-
let programDiagnostics = diagnostics.getDiagnostics(sourceFile.fileName);
656+
let fileProcessingDiagnosticsInFile = fileProcessingDiagnostics.getDiagnostics(sourceFile.fileName);
657+
let programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName);
649658

650-
return bindDiagnostics.concat(checkDiagnostics).concat(programDiagnostics);
659+
return bindDiagnostics.concat(checkDiagnostics).concat(fileProcessingDiagnosticsInFile).concat(programDiagnosticsInFile);
651660
});
652661
}
653662

@@ -664,7 +673,8 @@ namespace ts {
664673

665674
function getOptionsDiagnostics(): Diagnostic[] {
666675
let allDiagnostics: Diagnostic[] = [];
667-
addRange(allDiagnostics, diagnostics.getGlobalDiagnostics());
676+
addRange(allDiagnostics, fileProcessingDiagnostics.getGlobalDiagnostics())
677+
addRange(allDiagnostics, programDiagnostics.getGlobalDiagnostics());
668678
return sortAndDeduplicateDiagnostics(allDiagnostics);
669679
}
670680

@@ -772,10 +782,10 @@ namespace ts {
772782

773783
if (diagnostic) {
774784
if (refFile !== undefined && refEnd !== undefined && refPos !== undefined) {
775-
diagnostics.add(createFileDiagnostic(refFile, refPos, refEnd - refPos, diagnostic, ...diagnosticArgument));
785+
fileProcessingDiagnostics.add(createFileDiagnostic(refFile, refPos, refEnd - refPos, diagnostic, ...diagnosticArgument));
776786
}
777787
else {
778-
diagnostics.add(createCompilerDiagnostic(diagnostic, ...diagnosticArgument));
788+
fileProcessingDiagnostics.add(createCompilerDiagnostic(diagnostic, ...diagnosticArgument));
779789
}
780790
}
781791
}
@@ -797,11 +807,11 @@ namespace ts {
797807
// We haven't looked for this file, do so now and cache result
798808
let file = host.getSourceFile(fileName, options.target, hostErrorMessage => {
799809
if (refFile !== undefined && refPos !== undefined && refEnd !== undefined) {
800-
diagnostics.add(createFileDiagnostic(refFile, refPos, refEnd - refPos,
810+
fileProcessingDiagnostics.add(createFileDiagnostic(refFile, refPos, refEnd - refPos,
801811
Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage));
802812
}
803813
else {
804-
diagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage));
814+
fileProcessingDiagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage));
805815
}
806816
});
807817
filesByName.set(canonicalName, file);
@@ -837,11 +847,11 @@ namespace ts {
837847
let sourceFileName = useAbsolutePath ? getNormalizedAbsolutePath(file.fileName, host.getCurrentDirectory()) : file.fileName;
838848
if (canonicalName !== sourceFileName) {
839849
if (refFile !== undefined && refPos !== undefined && refEnd !== undefined) {
840-
diagnostics.add(createFileDiagnostic(refFile, refPos, refEnd - refPos,
850+
fileProcessingDiagnostics.add(createFileDiagnostic(refFile, refPos, refEnd - refPos,
841851
Diagnostics.File_name_0_differs_from_already_included_file_name_1_only_in_casing, fileName, sourceFileName));
842852
}
843853
else {
844-
diagnostics.add(createCompilerDiagnostic(Diagnostics.File_name_0_differs_from_already_included_file_name_1_only_in_casing, fileName, sourceFileName));
854+
fileProcessingDiagnostics.add(createCompilerDiagnostic(Diagnostics.File_name_0_differs_from_already_included_file_name_1_only_in_casing, fileName, sourceFileName));
845855
}
846856
}
847857
}
@@ -877,7 +887,7 @@ namespace ts {
877887
return;
878888

879889
function findModuleSourceFile(fileName: string, nameLiteral: Expression) {
880-
return findSourceFile(fileName, /* isDefaultLib */ false, file, nameLiteral.pos, nameLiteral.end);
890+
return findSourceFile(fileName, /* isDefaultLib */ false, file, skipTrivia(file.text, nameLiteral.pos), nameLiteral.end);
881891
}
882892
}
883893

@@ -902,7 +912,7 @@ namespace ts {
902912
for (let i = 0, n = Math.min(commonPathComponents.length, sourcePathComponents.length); i < n; i++) {
903913
if (commonPathComponents[i] !== sourcePathComponents[i]) {
904914
if (i === 0) {
905-
diagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files));
915+
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files));
906916
return;
907917
}
908918

@@ -931,7 +941,7 @@ namespace ts {
931941
if (!isDeclarationFile(sourceFile)) {
932942
let absoluteSourceFilePath = host.getCanonicalFileName(getNormalizedAbsolutePath(sourceFile.fileName, currentDirectory));
933943
if (absoluteSourceFilePath.indexOf(absoluteRootDirectoryPath) !== 0) {
934-
diagnostics.add(createCompilerDiagnostic(Diagnostics.File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files, sourceFile.fileName, options.rootDir));
944+
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files, sourceFile.fileName, options.rootDir));
935945
allFilesBelongToPath = false;
936946
}
937947
}
@@ -944,52 +954,52 @@ namespace ts {
944954
function verifyCompilerOptions() {
945955
if (options.isolatedModules) {
946956
if (options.declaration) {
947-
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "declaration", "isolatedModules"));
957+
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "declaration", "isolatedModules"));
948958
}
949959

950960
if (options.noEmitOnError) {
951-
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noEmitOnError", "isolatedModules"));
961+
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noEmitOnError", "isolatedModules"));
952962
}
953963

954964
if (options.out) {
955-
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "out", "isolatedModules"));
965+
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "out", "isolatedModules"));
956966
}
957967

958968
if (options.outFile) {
959-
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "outFile", "isolatedModules"));
969+
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "outFile", "isolatedModules"));
960970
}
961971
}
962972

963973
if (options.inlineSourceMap) {
964974
if (options.sourceMap) {
965-
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "sourceMap", "inlineSourceMap"));
975+
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "sourceMap", "inlineSourceMap"));
966976
}
967977
if (options.mapRoot) {
968-
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "mapRoot", "inlineSourceMap"));
978+
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "mapRoot", "inlineSourceMap"));
969979
}
970980
if (options.sourceRoot) {
971-
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "sourceRoot", "inlineSourceMap"));
981+
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "sourceRoot", "inlineSourceMap"));
972982
}
973983
}
974984

975985

976986
if (options.inlineSources) {
977987
if (!options.sourceMap && !options.inlineSourceMap) {
978-
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_inlineSources_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided));
988+
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_inlineSources_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided));
979989
}
980990
}
981991

982992
if (options.out && options.outFile) {
983-
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "out", "outFile"));
993+
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "out", "outFile"));
984994
}
985995

986996
if (!options.sourceMap && (options.mapRoot || options.sourceRoot)) {
987997
// Error to specify --mapRoot or --sourceRoot without mapSourceFiles
988998
if (options.mapRoot) {
989-
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "mapRoot", "sourceMap"));
999+
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "mapRoot", "sourceMap"));
9901000
}
9911001
if (options.sourceRoot) {
992-
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "sourceRoot", "sourceMap"));
1002+
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "sourceRoot", "sourceMap"));
9931003
}
9941004
return;
9951005
}
@@ -1000,24 +1010,24 @@ namespace ts {
10001010
let firstExternalModuleSourceFile = forEach(files, f => isExternalModule(f) ? f : undefined);
10011011
if (options.isolatedModules) {
10021012
if (!options.module && languageVersion < ScriptTarget.ES6) {
1003-
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES6_or_higher));
1013+
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES6_or_higher));
10041014
}
10051015

10061016
let firstNonExternalModuleSourceFile = forEach(files, f => !isExternalModule(f) && !isDeclarationFile(f) ? f : undefined);
10071017
if (firstNonExternalModuleSourceFile) {
10081018
let span = getErrorSpanForNode(firstNonExternalModuleSourceFile, firstNonExternalModuleSourceFile);
1009-
diagnostics.add(createFileDiagnostic(firstNonExternalModuleSourceFile, span.start, span.length, Diagnostics.Cannot_compile_namespaces_when_the_isolatedModules_flag_is_provided));
1019+
programDiagnostics.add(createFileDiagnostic(firstNonExternalModuleSourceFile, span.start, span.length, Diagnostics.Cannot_compile_namespaces_when_the_isolatedModules_flag_is_provided));
10101020
}
10111021
}
10121022
else if (firstExternalModuleSourceFile && languageVersion < ScriptTarget.ES6 && !options.module) {
10131023
// We cannot use createDiagnosticFromNode because nodes do not have parents yet
10141024
let span = getErrorSpanForNode(firstExternalModuleSourceFile, firstExternalModuleSourceFile.externalModuleIndicator);
1015-
diagnostics.add(createFileDiagnostic(firstExternalModuleSourceFile, span.start, span.length, Diagnostics.Cannot_compile_modules_unless_the_module_flag_is_provided));
1025+
programDiagnostics.add(createFileDiagnostic(firstExternalModuleSourceFile, span.start, span.length, Diagnostics.Cannot_compile_modules_unless_the_module_flag_is_provided));
10161026
}
10171027

10181028
// Cannot specify module gen target when in es6 or above
10191029
if (options.module && languageVersion >= ScriptTarget.ES6) {
1020-
diagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_compile_modules_into_commonjs_amd_system_or_umd_when_targeting_ES6_or_higher));
1030+
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_compile_modules_into_commonjs_amd_system_or_umd_when_targeting_ES6_or_higher));
10211031
}
10221032

10231033
// there has to be common source directory if user specified --outdir || --sourceRoot
@@ -1046,30 +1056,30 @@ namespace ts {
10461056

10471057
if (options.noEmit) {
10481058
if (options.out) {
1049-
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noEmit", "out"));
1059+
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noEmit", "out"));
10501060
}
10511061

10521062
if (options.outFile) {
1053-
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noEmit", "outFile"));
1063+
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noEmit", "outFile"));
10541064
}
10551065

10561066
if (options.outDir) {
1057-
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noEmit", "outDir"));
1067+
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noEmit", "outDir"));
10581068
}
10591069

10601070
if (options.declaration) {
1061-
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noEmit", "declaration"));
1071+
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noEmit", "declaration"));
10621072
}
10631073
}
10641074

10651075
if (options.emitDecoratorMetadata &&
10661076
!options.experimentalDecorators) {
1067-
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "emitDecoratorMetadata", "experimentalDecorators"));
1077+
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "emitDecoratorMetadata", "experimentalDecorators"));
10681078
}
10691079

10701080
if (options.experimentalAsyncFunctions &&
10711081
options.target !== ScriptTarget.ES6) {
1072-
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_experimentalAsyncFunctions_cannot_be_specified_when_targeting_ES5_or_lower));
1082+
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_experimentalAsyncFunctions_cannot_be_specified_when_targeting_ES5_or_lower));
10731083
}
10741084
}
10751085
}

src/compiler/types.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1359,6 +1359,7 @@ namespace ts {
13591359
/* @internal */ getSymbolCount(): number;
13601360
/* @internal */ getTypeCount(): number;
13611361

1362+
/* @internal */ getFileProcessingDiagnostics(): DiagnosticCollection;
13621363
// For testing purposes only.
13631364
/* @internal */ structureIsReused?: boolean;
13641365
}
@@ -2335,5 +2336,7 @@ namespace ts {
23352336
// operation caused diagnostics to be returned by storing and comparing the return value
23362337
// of this method before/after the operation is performed.
23372338
getModificationCount(): number;
2339+
2340+
/* @internal */ reattachFileDiagnostics(newFile: SourceFile): void;
23382341
}
23392342
}

src/compiler/utilities.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1507,12 +1507,23 @@ namespace ts {
15071507
add,
15081508
getGlobalDiagnostics,
15091509
getDiagnostics,
1510-
getModificationCount
1510+
getModificationCount,
1511+
reattachFileDiagnostics
15111512
};
15121513

15131514
function getModificationCount() {
15141515
return modificationCount;
15151516
}
1517+
1518+
function reattachFileDiagnostics(newFile: SourceFile): void {
1519+
if (!hasProperty(fileDiagnostics, newFile.fileName)) {
1520+
return;
1521+
}
1522+
1523+
for (let diagnostic of fileDiagnostics[newFile.fileName]) {
1524+
diagnostic.file = newFile;
1525+
}
1526+
}
15161527

15171528
function add(diagnostic: Diagnostic): void {
15181529
let diagnostics: Diagnostic[];

0 commit comments

Comments
 (0)