Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit a0fe072

Browse filesBrowse files
authored
Merge pull request microsoft#22613 from Microsoft/configFileErrors
Make config file parsing errors available through program and expose API
2 parents d5a7dc1 + 7329eb1 commit a0fe072
Copy full SHA for a0fe072

9 files changed

+180-121Lines changed: 180 additions & 121 deletions

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎src/compiler/builder.ts‎

Copy file name to clipboardExpand all lines: src/compiler/builder.ts
+35-18Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -218,29 +218,40 @@ namespace ts {
218218
newProgram: Program;
219219
host: BuilderProgramHost;
220220
oldProgram: BuilderProgram | undefined;
221+
configFileParsingDiagnostics: ReadonlyArray<Diagnostic>;
221222
}
222223

223-
export function getBuilderCreationParameters(newProgramOrRootNames: Program | ReadonlyArray<string>, hostOrOptions: BuilderProgramHost | CompilerOptions, oldProgramOrHost?: CompilerHost | BuilderProgram, oldProgram?: BuilderProgram): BuilderCreationParameters {
224+
export function getBuilderCreationParameters(newProgramOrRootNames: Program | ReadonlyArray<string> | undefined, hostOrOptions: BuilderProgramHost | CompilerOptions | undefined, oldProgramOrHost?: BuilderProgram | CompilerHost, configFileParsingDiagnosticsOrOldProgram?: ReadonlyArray<Diagnostic> | BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): BuilderCreationParameters {
224225
let host: BuilderProgramHost;
225226
let newProgram: Program;
226-
if (isArray(newProgramOrRootNames)) {
227-
newProgram = createProgram(newProgramOrRootNames, hostOrOptions as CompilerOptions, oldProgramOrHost as CompilerHost, oldProgram && oldProgram.getProgram());
227+
let oldProgram: BuilderProgram;
228+
if (newProgramOrRootNames === undefined) {
229+
Debug.assert(hostOrOptions === undefined);
230+
host = oldProgramOrHost as CompilerHost;
231+
oldProgram = configFileParsingDiagnosticsOrOldProgram as BuilderProgram;
232+
Debug.assert(!!oldProgram);
233+
newProgram = oldProgram.getProgram();
234+
}
235+
else if (isArray(newProgramOrRootNames)) {
236+
oldProgram = configFileParsingDiagnosticsOrOldProgram as BuilderProgram;
237+
newProgram = createProgram(newProgramOrRootNames, hostOrOptions as CompilerOptions, oldProgramOrHost as CompilerHost, oldProgram && oldProgram.getProgram(), configFileParsingDiagnostics);
228238
host = oldProgramOrHost as CompilerHost;
229239
}
230240
else {
231241
newProgram = newProgramOrRootNames;
232242
host = hostOrOptions as BuilderProgramHost;
233243
oldProgram = oldProgramOrHost as BuilderProgram;
244+
configFileParsingDiagnostics = configFileParsingDiagnosticsOrOldProgram as ReadonlyArray<Diagnostic>;
234245
}
235-
return { host, newProgram, oldProgram };
246+
return { host, newProgram, oldProgram, configFileParsingDiagnostics: configFileParsingDiagnostics || emptyArray };
236247
}
237248

238249
export function createBuilderProgram(kind: BuilderProgramKind.SemanticDiagnosticsBuilderProgram, builderCreationParameters: BuilderCreationParameters): SemanticDiagnosticsBuilderProgram;
239250
export function createBuilderProgram(kind: BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram, builderCreationParameters: BuilderCreationParameters): EmitAndSemanticDiagnosticsBuilderProgram;
240-
export function createBuilderProgram(kind: BuilderProgramKind, { newProgram, host, oldProgram }: BuilderCreationParameters) {
251+
export function createBuilderProgram(kind: BuilderProgramKind, { newProgram, host, oldProgram, configFileParsingDiagnostics }: BuilderCreationParameters) {
241252
// Return same program if underlying program doesnt change
242253
let oldState = oldProgram && oldProgram.getState();
243-
if (oldState && newProgram === oldState.program) {
254+
if (oldState && newProgram === oldState.program && configFileParsingDiagnostics !== newProgram.getConfigFileParsingDiagnostics()) {
244255
newProgram = undefined;
245256
oldState = undefined;
246257
return oldProgram;
@@ -269,6 +280,7 @@ namespace ts {
269280
getSourceFiles: () => state.program.getSourceFiles(),
270281
getOptionsDiagnostics: cancellationToken => state.program.getOptionsDiagnostics(cancellationToken),
271282
getGlobalDiagnostics: cancellationToken => state.program.getGlobalDiagnostics(cancellationToken),
283+
getConfigFileParsingDiagnostics: () => configFileParsingDiagnostics || state.program.getConfigFileParsingDiagnostics(),
272284
getSyntacticDiagnostics: (sourceFile, cancellationToken) => state.program.getSyntacticDiagnostics(sourceFile, cancellationToken),
273285
getSemanticDiagnostics,
274286
emit,
@@ -471,6 +483,10 @@ namespace ts {
471483
* Get the diagnostics that dont belong to any file
472484
*/
473485
getGlobalDiagnostics(cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
486+
/**
487+
* Get the diagnostics from config file parsing
488+
*/
489+
getConfigFileParsingDiagnostics(): ReadonlyArray<Diagnostic>;
474490
/**
475491
* Get the syntax diagnostics, for all source files if source file is not supplied
476492
*/
@@ -533,29 +549,29 @@ namespace ts {
533549
/**
534550
* Create the builder to manage semantic diagnostics and cache them
535551
*/
536-
export function createSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram?: SemanticDiagnosticsBuilderProgram): SemanticDiagnosticsBuilderProgram;
537-
export function createSemanticDiagnosticsBuilderProgram(rootNames: ReadonlyArray<string>, options: CompilerOptions, host?: CompilerHost, oldProgram?: SemanticDiagnosticsBuilderProgram): SemanticDiagnosticsBuilderProgram;
538-
export function createSemanticDiagnosticsBuilderProgram(newProgramOrRootNames: Program | ReadonlyArray<string>, hostOrOptions: BuilderProgramHost | CompilerOptions, oldProgramOrHost?: CompilerHost | SemanticDiagnosticsBuilderProgram, oldProgram?: SemanticDiagnosticsBuilderProgram) {
539-
return createBuilderProgram(BuilderProgramKind.SemanticDiagnosticsBuilderProgram, getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, oldProgram));
552+
export function createSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram?: SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): SemanticDiagnosticsBuilderProgram;
553+
export function createSemanticDiagnosticsBuilderProgram(rootNames: ReadonlyArray<string>, options: CompilerOptions, host?: CompilerHost, oldProgram?: SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): SemanticDiagnosticsBuilderProgram;
554+
export function createSemanticDiagnosticsBuilderProgram(newProgramOrRootNames: Program | ReadonlyArray<string>, hostOrOptions: BuilderProgramHost | CompilerOptions, oldProgramOrHost?: CompilerHost | SemanticDiagnosticsBuilderProgram, configFileParsingDiagnosticsOrOldProgram?: ReadonlyArray<Diagnostic> | SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>) {
555+
return createBuilderProgram(BuilderProgramKind.SemanticDiagnosticsBuilderProgram, getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics));
540556
}
541557

542558
/**
543559
* Create the builder that can handle the changes in program and iterate through changed files
544560
* to emit the those files and manage semantic diagnostics cache as well
545561
*/
546-
export function createEmitAndSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram): EmitAndSemanticDiagnosticsBuilderProgram;
547-
export function createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: ReadonlyArray<string>, options: CompilerOptions, host?: CompilerHost, oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram): EmitAndSemanticDiagnosticsBuilderProgram;
548-
export function createEmitAndSemanticDiagnosticsBuilderProgram(newProgramOrRootNames: Program | ReadonlyArray<string>, hostOrOptions: BuilderProgramHost | CompilerOptions, oldProgramOrHost?: CompilerHost | EmitAndSemanticDiagnosticsBuilderProgram, oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram) {
549-
return createBuilderProgram(BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram, getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, oldProgram));
562+
export function createEmitAndSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): EmitAndSemanticDiagnosticsBuilderProgram;
563+
export function createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: ReadonlyArray<string>, options: CompilerOptions, host?: CompilerHost, oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): EmitAndSemanticDiagnosticsBuilderProgram;
564+
export function createEmitAndSemanticDiagnosticsBuilderProgram(newProgramOrRootNames: Program | ReadonlyArray<string>, hostOrOptions: BuilderProgramHost | CompilerOptions, oldProgramOrHost?: CompilerHost | EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnosticsOrOldProgram?: ReadonlyArray<Diagnostic> | EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>) {
565+
return createBuilderProgram(BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram, getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics));
550566
}
551567

552568
/**
553569
* Creates a builder thats just abstraction over program and can be used with watch
554570
*/
555-
export function createAbstractBuilder(newProgram: Program, host: BuilderProgramHost, oldProgram?: BuilderProgram): BuilderProgram;
556-
export function createAbstractBuilder(rootNames: ReadonlyArray<string>, options: CompilerOptions, host?: CompilerHost, oldProgram?: BuilderProgram): BuilderProgram;
557-
export function createAbstractBuilder(newProgramOrRootNames: Program | ReadonlyArray<string>, hostOrOptions: BuilderProgramHost | CompilerOptions, oldProgramOrHost?: CompilerHost | BuilderProgram, oldProgram?: BuilderProgram): BuilderProgram {
558-
const { newProgram: program } = getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, oldProgram);
571+
export function createAbstractBuilder(newProgram: Program, host: BuilderProgramHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): BuilderProgram;
572+
export function createAbstractBuilder(rootNames: ReadonlyArray<string>, options: CompilerOptions, host?: CompilerHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): BuilderProgram;
573+
export function createAbstractBuilder(newProgramOrRootNames: Program | ReadonlyArray<string>, hostOrOptions: BuilderProgramHost | CompilerOptions, oldProgramOrHost?: CompilerHost | BuilderProgram, configFileParsingDiagnosticsOrOldProgram?: ReadonlyArray<Diagnostic> | BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): BuilderProgram {
574+
const { newProgram: program } = getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics);
559575
return {
560576
// Only return program, all other methods are not implemented
561577
getProgram: () => program,
@@ -565,6 +581,7 @@ namespace ts {
565581
getSourceFiles: notImplemented,
566582
getOptionsDiagnostics: notImplemented,
567583
getGlobalDiagnostics: notImplemented,
584+
getConfigFileParsingDiagnostics: notImplemented,
568585
getSyntacticDiagnostics: notImplemented,
569586
getSemanticDiagnostics: notImplemented,
570587
emit: notImplemented,
Collapse file

‎src/compiler/program.ts‎

Copy file name to clipboardExpand all lines: src/compiler/program.ts
+15-2Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ namespace ts {
198198

199199
export function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[] {
200200
const diagnostics = [
201+
...program.getConfigFileParsingDiagnostics(),
201202
...program.getOptionsDiagnostics(cancellationToken),
202203
...program.getSyntacticDiagnostics(sourceFile, cancellationToken),
203204
...program.getGlobalDiagnostics(cancellationToken),
@@ -454,6 +455,12 @@ namespace ts {
454455
}
455456
}
456457

458+
export function getConfigFileParsingDiagnostics(configFileParseResult: ParsedCommandLine): ReadonlyArray<Diagnostic> {
459+
return configFileParseResult.options.configFile ?
460+
configFileParseResult.options.configFile.parseDiagnostics.concat(configFileParseResult.errors) :
461+
configFileParseResult.errors;
462+
}
463+
457464
/**
458465
* Determined if source file needs to be re-created even if its text hasn't changed
459466
*/
@@ -485,9 +492,10 @@ namespace ts {
485492
* @param options - The compiler options which should be used.
486493
* @param host - The host interacts with the underlying file system.
487494
* @param oldProgram - Reuses an old program structure.
495+
* @param configFileParsingDiagnostics - error during config file parsing
488496
* @returns A 'Program' object.
489497
*/
490-
export function createProgram(rootNames: ReadonlyArray<string>, options: CompilerOptions, host?: CompilerHost, oldProgram?: Program): Program {
498+
export function createProgram(rootNames: ReadonlyArray<string>, options: CompilerOptions, host?: CompilerHost, oldProgram?: Program, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): Program {
491499
let program: Program;
492500
let files: SourceFile[] = [];
493501
let commonSourceDirectory: string;
@@ -665,7 +673,8 @@ namespace ts {
665673
getSourceFileFromReference,
666674
sourceFileToPackageName,
667675
redirectTargetsSet,
668-
isEmittedFile
676+
isEmittedFile,
677+
getConfigFileParsingDiagnostics
669678
};
670679

671680
verifyCompilerOptions();
@@ -1568,6 +1577,10 @@ namespace ts {
15681577
return sortAndDeduplicateDiagnostics(getDiagnosticsProducingTypeChecker().getGlobalDiagnostics().slice());
15691578
}
15701579

1580+
function getConfigFileParsingDiagnostics(): ReadonlyArray<Diagnostic> {
1581+
return configFileParsingDiagnostics || emptyArray;
1582+
}
1583+
15711584
function processRootFile(fileName: string, isDefaultLib: boolean) {
15721585
processSourceFile(normalizePath(fileName), isDefaultLib, /*packageId*/ undefined);
15731586
}
Collapse file

‎src/compiler/tsc.ts‎

Copy file name to clipboardExpand all lines: src/compiler/tsc.ts
+4-7Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ namespace ts {
117117
createWatchOfConfigFile(configParseResult, commandLineOptions);
118118
}
119119
else {
120-
performCompilation(configParseResult.fileNames, configParseResult.options);
120+
performCompilation(configParseResult.fileNames, configParseResult.options, getConfigFileParsingDiagnostics(configParseResult));
121121
}
122122
}
123123
else {
@@ -139,11 +139,11 @@ namespace ts {
139139
}
140140
}
141141

142-
function performCompilation(rootFileNames: string[], compilerOptions: CompilerOptions) {
142+
function performCompilation(rootFileNames: string[], compilerOptions: CompilerOptions, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>) {
143143
const compilerHost = createCompilerHost(compilerOptions);
144144
enableStatistics(compilerOptions);
145145

146-
const program = createProgram(rootFileNames, compilerOptions, compilerHost);
146+
const program = createProgram(rootFileNames, compilerOptions, compilerHost, /*oldProgram*/ undefined, configFileParsingDiagnostics);
147147
const exitStatus = emitFilesAndReportErrors(program, reportDiagnostic, s => sys.write(s + sys.newLine));
148148
reportStatistics(program);
149149
return sys.exit(exitStatus);
@@ -169,10 +169,7 @@ namespace ts {
169169
function createWatchOfConfigFile(configParseResult: ParsedCommandLine, optionsToExtend: CompilerOptions) {
170170
const watchCompilerHost = createWatchCompilerHostOfConfigFile(configParseResult.options.configFilePath, optionsToExtend, sys, /*createProgram*/ undefined, reportDiagnostic, createWatchStatusReporter(configParseResult.options));
171171
updateWatchCompilationHost(watchCompilerHost);
172-
watchCompilerHost.rootFiles = configParseResult.fileNames;
173-
watchCompilerHost.options = configParseResult.options;
174-
watchCompilerHost.configFileSpecs = configParseResult.configFileSpecs;
175-
watchCompilerHost.configFileWildCardDirectories = configParseResult.wildcardDirectories;
172+
watchCompilerHost.configFileParsingResult = configParseResult;
176173
createWatchProgram(watchCompilerHost);
177174
}
178175

Collapse file

‎src/compiler/types.ts‎

Copy file name to clipboardExpand all lines: src/compiler/types.ts
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2671,6 +2671,7 @@ namespace ts {
26712671
getSyntacticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
26722672
getSemanticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
26732673
getDeclarationDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
2674+
getConfigFileParsingDiagnostics(): ReadonlyArray<Diagnostic>;
26742675

26752676
/**
26762677
* Gets a type checker that can be used to semantically analyze source files in the program.

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.