Exclude Json files from Project reference redirects from files to be emitted list

Fixes #30382
This commit is contained in:
Sheetal Nandi 2019-03-14 10:58:57 -07:00
parent a6f7ec3464
commit bd229b5ed1
14 changed files with 58 additions and 55 deletions

View file

@ -980,7 +980,7 @@ namespace ts {
backupState: noop,
restoreState: noop,
getProgram: notImplemented,
getProgramOrUndefined: () => undefined,
getProgramOrUndefined: returnUndefined,
releaseProgram: noop,
getCompilerOptions: () => state.compilerOptions,
getSourceFile: notImplemented,

View file

@ -1614,6 +1614,9 @@ namespace ts {
/** Do nothing and return true */
export function returnTrue(): true { return true; }
/** Do nothing and return undefined */
export function returnUndefined(): undefined { return undefined; }
/** Returns its argument. */
export function identity<T>(x: T) { return x; }

View file

@ -680,11 +680,12 @@ namespace ts {
getCompilerOptions: () => config.options,
getCurrentDirectory: () => host.getCurrentDirectory(),
getNewLine: () => host.getNewLine(),
getSourceFile: () => undefined,
getSourceFileByPath: () => undefined,
getSourceFile: returnUndefined,
getSourceFileByPath: returnUndefined,
getSourceFiles: () => sourceFilesForJsEmit,
getLibFileFromReference: notImplemented,
isSourceFileFromExternalLibrary: returnFalse,
getResolvedProjectReferenceToRedirect: returnUndefined,
writeFile: (name, text, writeByteOrderMark) => {
switch (name) {
case jsFilePath:
@ -721,7 +722,7 @@ namespace ts {
fileExists: f => host.fileExists(f),
directoryExists: host.directoryExists && (f => host.directoryExists!(f)),
useCaseSensitiveFileNames: () => host.useCaseSensitiveFileNames(),
getProgramBuildInfo: () => undefined
getProgramBuildInfo: returnUndefined
};
emitFiles(notImplementedResolver, emitHost, /*targetSourceFile*/ undefined, /*emitOnlyDtsFiles*/ false, getTransformers(config.options));
return outputFiles;

View file

@ -3405,7 +3405,7 @@ namespace ts {
export const nullTransformationContext: TransformationContext = {
enableEmitNotification: noop,
enableSubstitution: noop,
endLexicalEnvironment: () => undefined,
endLexicalEnvironment: returnUndefined,
getCompilerOptions: notImplemented,
getEmitHost: notImplemented,
getEmitResolver: notImplemented,

View file

@ -979,7 +979,7 @@ namespace ts {
function getCommonSourceDirectory() {
if (commonSourceDirectory === undefined) {
const emittedFiles = filter(files, file => sourceFileMayBeEmitted(file, options, isSourceFileFromExternalLibrary));
const emittedFiles = filter(files, file => sourceFileMayBeEmitted(file, options, isSourceFileFromExternalLibrary, getResolvedProjectReferenceToRedirect));
if (options.rootDir && checkSourceFilesBelongToPath(emittedFiles, options.rootDir)) {
// If a rootDir is specified use it as the commonSourceDirectory
commonSourceDirectory = getNormalizedAbsolutePath(options.rootDir, currentDirectory);
@ -1425,6 +1425,7 @@ namespace ts {
getSourceFiles: program.getSourceFiles,
getLibFileFromReference: program.getLibFileFromReference,
isSourceFileFromExternalLibrary,
getResolvedProjectReferenceToRedirect,
writeFile: writeFileCallback || (
(fileName, data, writeByteOrderMark, onError, sourceFiles) => host.writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles)),
isEmitBlocked,
@ -2740,13 +2741,14 @@ namespace ts {
// List of collected files is complete; validate exhautiveness if this is a project with a file list
if (options.composite) {
const sourceFiles = files.filter(f => !f.isDeclarationFile);
if (rootNames.length < sourceFiles.length) {
const normalizedRootNames = rootNames.map(r => normalizePath(r).toLowerCase());
for (const file of sourceFiles.map(f => normalizePath(f.path).toLowerCase())) {
if (normalizedRootNames.indexOf(file) === -1) {
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.File_0_is_not_in_project_file_list_Projects_must_list_all_files_or_use_an_include_pattern, file));
}
const rootPaths = rootNames.map(r => toPath(r));
for (const file of files) {
// Ignore declaration files
if (file.isDeclarationFile) continue;
// Ignore json file thats from project reference
if (isJsonSourceFile(file) && getResolvedProjectReferenceToRedirect(file.fileName)) continue;
if (rootPaths.indexOf(file.path) === -1) {
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.File_0_is_not_in_project_file_list_Projects_must_list_all_files_or_use_an_include_pattern, file.fileName));
}
}
}
@ -3158,7 +3160,7 @@ namespace ts {
readFile: f => directoryStructureHost.readFile(f),
useCaseSensitiveFileNames: host.useCaseSensitiveFileNames(),
getCurrentDirectory: () => host.getCurrentDirectory(),
onUnRecoverableConfigFileDiagnostic: host.onUnRecoverableConfigFileDiagnostic || (() => undefined),
onUnRecoverableConfigFileDiagnostic: host.onUnRecoverableConfigFileDiagnostic || returnUndefined,
trace: host.trace ? (s) => host.trace!(s) : undefined
};
}

View file

@ -339,7 +339,7 @@ namespace ts {
function createSolutionBuilderHostBase<T extends BuilderProgram>(system: System, createProgram: CreateProgram<T> | undefined, reportDiagnostic?: DiagnosticReporter, reportSolutionBuilderStatus?: DiagnosticReporter) {
const host = createProgramHost(system, createProgram) as SolutionBuilderHostBase<T>;
host.getModifiedTime = system.getModifiedTime ? path => system.getModifiedTime!(path) : () => undefined;
host.getModifiedTime = system.getModifiedTime ? path => system.getModifiedTime!(path) : returnUndefined;
host.setModifiedTime = system.setModifiedTime ? (path, date) => system.setModifiedTime!(path, date) : noop;
host.deleteFile = system.deleteFile ? path => system.deleteFile!(path) : noop;
host.reportDiagnostic = reportDiagnostic || createDiagnosticReporter(system);
@ -660,15 +660,16 @@ namespace ts {
}
}
// Collect the expected outputs of this project
const outputs = getAllProjectOutputs(project, !host.useCaseSensitiveFileNames());
if (outputs.length === 0) {
// Container if no files are specified in the project
if (!project.fileNames.length && !canJsonReportNoInutFiles(project.raw)) {
return {
type: UpToDateStatusType.ContainerOnly
};
}
// Collect the expected outputs of this project
const outputs = getAllProjectOutputs(project, !host.useCaseSensitiveFileNames());
// Now see if all outputs are newer than the newest input
let oldestOutputFileName = "(none)";
let oldestOutputFileTime = maximumDate;

View file

@ -5337,6 +5337,7 @@ namespace ts {
getCurrentDirectory(): string;
isSourceFileFromExternalLibrary(file: SourceFile): boolean;
getResolvedProjectReferenceToRedirect(fileName: string): ResolvedProjectReference | undefined;
getLibFileFromReference(ref: FileReference): SourceFile | undefined;
getCommonSourceDirectory(): string;

View file

@ -3422,22 +3422,26 @@ namespace ts {
export function getSourceFilesToEmit(host: EmitHost, targetSourceFile?: SourceFile): ReadonlyArray<SourceFile> {
const options = host.getCompilerOptions();
const isSourceFileFromExternalLibrary = (file: SourceFile) => host.isSourceFileFromExternalLibrary(file);
const getResolvedProjectReferenceToRedirect = (fileName: string) => host.getResolvedProjectReferenceToRedirect(fileName);
if (options.outFile || options.out) {
const moduleKind = getEmitModuleKind(options);
const moduleEmitEnabled = options.emitDeclarationOnly || moduleKind === ModuleKind.AMD || moduleKind === ModuleKind.System;
// Can emit only sources that are not declaration file and are either non module code or module with --module or --target es6 specified
return filter(host.getSourceFiles(), sourceFile =>
(moduleEmitEnabled || !isExternalModule(sourceFile)) && sourceFileMayBeEmitted(sourceFile, options, isSourceFileFromExternalLibrary));
(moduleEmitEnabled || !isExternalModule(sourceFile)) && sourceFileMayBeEmitted(sourceFile, options, isSourceFileFromExternalLibrary, getResolvedProjectReferenceToRedirect));
}
else {
const sourceFiles = targetSourceFile === undefined ? host.getSourceFiles() : [targetSourceFile];
return filter(sourceFiles, sourceFile => sourceFileMayBeEmitted(sourceFile, options, isSourceFileFromExternalLibrary));
return filter(sourceFiles, sourceFile => sourceFileMayBeEmitted(sourceFile, options, isSourceFileFromExternalLibrary, getResolvedProjectReferenceToRedirect));
}
}
/** Don't call this for `--outFile`, just for `--outDir` or plain emit. `--outFile` needs additional checks. */
export function sourceFileMayBeEmitted(sourceFile: SourceFile, options: CompilerOptions, isSourceFileFromExternalLibrary: (file: SourceFile) => boolean) {
return !(options.noEmitForJsFiles && isSourceFileJS(sourceFile)) && !sourceFile.isDeclarationFile && !isSourceFileFromExternalLibrary(sourceFile);
export function sourceFileMayBeEmitted(sourceFile: SourceFile, options: CompilerOptions, isSourceFileFromExternalLibrary: (file: SourceFile) => boolean, getResolvedProjectReferenceToRedirect: (fileName: string) => ResolvedProjectReference | undefined) {
return !(options.noEmitForJsFiles && isSourceFileJS(sourceFile)) &&
!sourceFile.isDeclarationFile &&
!isSourceFileFromExternalLibrary(sourceFile) &&
!(isJsonSourceFile(sourceFile) && getResolvedProjectReferenceToRedirect(sourceFile.fileName));
}
export function getSourceFilePathInNewDir(fileName: string, host: EmitHost, newDirPath: string): string {

View file

@ -132,22 +132,15 @@ export default hello.hello`);
[Diagnostics.Building_project_0, `/${stringsConfigFile}`],
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, mainConfigFile, "src/main/index.js"],
[Diagnostics.Building_project_0, `/${mainConfigFile}`],
[Diagnostics.File_0_is_not_in_project_file_list_Projects_must_list_all_files_or_use_an_include_pattern, "/src/strings/foo.json"],
[Diagnostics.Project_0_can_t_be_built_because_its_dependency_1_has_errors, configFile, mainConfigFile],
[Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_has_errors, `/${configFile}`, `/${mainConfigFile}`]
);
assert.isFalse(fs.existsSync(expectedOutput), `Expect file ${expectedOutput} to not exist because of errors`);
assert(fs.existsSync(expectedOutput), `Expect file ${expectedOutput} to exist`);
host.clearDiagnostics();
builder.resetBuildContext();
builder.buildAllProjects();
host.assertDiagnosticMessages(
getExpectedDiagnosticForProjectsInBuild(stringsConfigFile, mainConfigFile, configFile),
[Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, stringsConfigFile, "src/strings/foo.json", "src/strings/tsconfig.tsbuildinfo"],
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, mainConfigFile, "src/main/index.js"],
[Diagnostics.Building_project_0, `/${mainConfigFile}`],
[Diagnostics.File_0_is_not_in_project_file_list_Projects_must_list_all_files_or_use_an_include_pattern, "/src/strings/foo.json"],
[Diagnostics.Project_0_can_t_be_built_because_its_dependency_1_has_errors, configFile, mainConfigFile],
[Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_has_errors, `/${configFile}`, `/${mainConfigFile}`]
[Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, mainConfigFile, "src/main/index.ts", "src/main/index.js"],
);
});
});

View file

@ -64,7 +64,7 @@ namespace ts.projectSystem {
msg: noop,
startGroup: noop,
endGroup: noop,
getLogFileName: () => undefined,
getLogFileName: returnUndefined,
};
export function createHasErrorMessageLogger() {

View file

@ -216,7 +216,7 @@ namespace ts.projectSystem {
},
startGroup: noop,
endGroup: noop,
getLogFileName: () => undefined
getLogFileName: returnUndefined
};
return {
errorLogger,

View file

@ -8,7 +8,7 @@ namespace ts.server {
newLine: "\n",
useCaseSensitiveFileNames: true,
write(s): void { lastWrittenToHost = s; },
readFile: () => undefined,
readFile: returnUndefined,
writeFile: noop,
resolvePath(): string { return undefined!; }, // TODO: GH#18217
fileExists: () => false,

View file

@ -1,8 +1,5 @@
{
"extends": "../tsconfig.json",
"include": [
"./**/*.ts",
"./**/*.json"
],
"include": [ "foo.json" ],
"references": []
}

View file

@ -1,19 +1,20 @@
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"rootDir": "./",
"composite": true,
"resolveJsonModule": true,
"strict": true,
"esModuleInterop": true
},
"references": [
{
"path": "./strings/tsconfig.json"
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"rootDir": "./",
"composite": true,
"resolveJsonModule": true,
"strict": true,
"esModuleInterop": true
},
{
"path": "./main/tsconfig.json"
}
]
"references": [
{
"path": "./strings/tsconfig.json"
},
{
"path": "./main/tsconfig.json"
}
],
"files": []
}