|
|
|
|
@@ -2568,108 +2568,25 @@ namespace ts {
|
|
|
|
|
* @param host An EmitHost.
|
|
|
|
|
* @param targetSourceFile An optional target source file to emit.
|
|
|
|
|
*/
|
|
|
|
|
export function getSourceFilesToEmit(host: EmitHost, targetSourceFile?: SourceFile) {
|
|
|
|
|
export function getSourceFilesToEmit(host: EmitHost, targetSourceFile?: SourceFile): SourceFile[] {
|
|
|
|
|
const options = host.getCompilerOptions();
|
|
|
|
|
const isSourceFileFromExternalLibrary = (file: SourceFile) => host.isSourceFileFromExternalLibrary(file);
|
|
|
|
|
if (options.outFile || options.out) {
|
|
|
|
|
const moduleKind = getEmitModuleKind(options);
|
|
|
|
|
const moduleEmitEnabled = moduleKind === ModuleKind.AMD || moduleKind === ModuleKind.System;
|
|
|
|
|
const sourceFiles = getAllEmittableSourceFiles();
|
|
|
|
|
// 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(sourceFiles, moduleEmitEnabled ? isNonDeclarationFile : isBundleEmitNonExternalModule);
|
|
|
|
|
return filter(host.getSourceFiles(), sourceFile =>
|
|
|
|
|
(moduleEmitEnabled || !isExternalModule(sourceFile)) && sourceFileMayBeEmitted(sourceFile, options, isSourceFileFromExternalLibrary));
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
const sourceFiles = targetSourceFile === undefined ? getAllEmittableSourceFiles() : [targetSourceFile];
|
|
|
|
|
return filterSourceFilesInDirectory(sourceFiles, file => host.isSourceFileFromExternalLibrary(file));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getAllEmittableSourceFiles() {
|
|
|
|
|
return options.noEmitForJsFiles ? filter(host.getSourceFiles(), sourceFile => !isSourceFileJavaScript(sourceFile)) : host.getSourceFiles();
|
|
|
|
|
const sourceFiles = targetSourceFile === undefined ? host.getSourceFiles() : [targetSourceFile];
|
|
|
|
|
return filter(sourceFiles, sourceFile => sourceFileMayBeEmitted(sourceFile, options, isSourceFileFromExternalLibrary));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Don't call this for `--outFile`, just for `--outDir` or plain emit. */
|
|
|
|
|
export function filterSourceFilesInDirectory(sourceFiles: SourceFile[], isSourceFileFromExternalLibrary: (file: SourceFile) => boolean): SourceFile[] {
|
|
|
|
|
return filter(sourceFiles, file => shouldEmitInDirectory(file, isSourceFileFromExternalLibrary));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function isNonDeclarationFile(sourceFile: SourceFile) {
|
|
|
|
|
return !isDeclarationFile(sourceFile);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Whether a file should be emitted in a non-`--outFile` case.
|
|
|
|
|
* Don't emit if source file is a declaration file, or was located under node_modules
|
|
|
|
|
*/
|
|
|
|
|
function shouldEmitInDirectory(sourceFile: SourceFile, isSourceFileFromExternalLibrary: (file: SourceFile) => boolean): boolean {
|
|
|
|
|
return isNonDeclarationFile(sourceFile) && !isSourceFileFromExternalLibrary(sourceFile);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function isBundleEmitNonExternalModule(sourceFile: SourceFile) {
|
|
|
|
|
return isNonDeclarationFile(sourceFile) && !isExternalModule(sourceFile);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Iterates over each source file to emit. The source files are expected to have been
|
|
|
|
|
* transformed for use by the pretty printer.
|
|
|
|
|
*
|
|
|
|
|
* Originally part of `forEachExpectedEmitFile`, this functionality was extracted to support
|
|
|
|
|
* transformations.
|
|
|
|
|
*
|
|
|
|
|
* @param host An EmitHost.
|
|
|
|
|
* @param sourceFiles The transformed source files to emit.
|
|
|
|
|
* @param action The action to execute.
|
|
|
|
|
*/
|
|
|
|
|
export function forEachTransformedEmitFile(host: EmitHost, sourceFiles: SourceFile[],
|
|
|
|
|
action: (jsFilePath: string, sourceMapFilePath: string, declarationFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean) => void,
|
|
|
|
|
emitOnlyDtsFiles?: boolean) {
|
|
|
|
|
const options = host.getCompilerOptions();
|
|
|
|
|
// Emit on each source file
|
|
|
|
|
if (options.outFile || options.out) {
|
|
|
|
|
onBundledEmit(sourceFiles);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
for (const sourceFile of sourceFiles) {
|
|
|
|
|
// Don't emit if source file is a declaration file, or was located under node_modules
|
|
|
|
|
if (!isDeclarationFile(sourceFile) && !host.isSourceFileFromExternalLibrary(sourceFile)) {
|
|
|
|
|
onSingleFileEmit(host, sourceFile);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function onSingleFileEmit(host: EmitHost, sourceFile: SourceFile) {
|
|
|
|
|
// JavaScript files are always LanguageVariant.JSX, as JSX syntax is allowed in .js files also.
|
|
|
|
|
// So for JavaScript files, '.jsx' is only emitted if the input was '.jsx', and JsxEmit.Preserve.
|
|
|
|
|
// For TypeScript, the only time to emit with a '.jsx' extension, is on JSX input, and JsxEmit.Preserve
|
|
|
|
|
let extension = ".js";
|
|
|
|
|
if (options.jsx === JsxEmit.Preserve) {
|
|
|
|
|
if (isSourceFileJavaScript(sourceFile)) {
|
|
|
|
|
if (fileExtensionIs(sourceFile.fileName, ".jsx")) {
|
|
|
|
|
extension = ".jsx";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (sourceFile.languageVariant === LanguageVariant.JSX) {
|
|
|
|
|
// TypeScript source file preserving JSX syntax
|
|
|
|
|
extension = ".jsx";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
const jsFilePath = getOwnEmitOutputFilePath(sourceFile, host, extension);
|
|
|
|
|
const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
|
|
|
|
|
const declarationFilePath = !isSourceFileJavaScript(sourceFile) && (options.declaration || emitOnlyDtsFiles) ? getDeclarationEmitOutputFilePath(sourceFile, host) : undefined;
|
|
|
|
|
action(jsFilePath, sourceMapFilePath, declarationFilePath, [sourceFile], /*isBundledEmit*/ false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function onBundledEmit(sourceFiles: SourceFile[]) {
|
|
|
|
|
if (sourceFiles.length) {
|
|
|
|
|
const jsFilePath = options.outFile || options.out;
|
|
|
|
|
const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
|
|
|
|
|
const declarationFilePath = options.declaration ? removeFileExtension(jsFilePath) + ".d.ts" : undefined;
|
|
|
|
|
action(jsFilePath, sourceMapFilePath, declarationFilePath, sourceFiles, /*isBundledEmit*/ true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getSourceMapFilePath(jsFilePath: string, options: CompilerOptions) {
|
|
|
|
|
return options.sourceMap ? jsFilePath + ".map" : undefined;
|
|
|
|
|
/** 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 && isSourceFileJavaScript(sourceFile)) && !isDeclarationFile(sourceFile) && !isSourceFileFromExternalLibrary(sourceFile);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@@ -2685,64 +2602,55 @@ namespace ts {
|
|
|
|
|
action: (emitFileNames: EmitFileNames, sourceFiles: SourceFile[], isBundledEmit: boolean, emitOnlyDtsFiles: boolean) => void,
|
|
|
|
|
targetSourceFile?: SourceFile,
|
|
|
|
|
emitOnlyDtsFiles?: boolean) {
|
|
|
|
|
forEachEmittedFile(host, getSourceFilesToEmit(host, targetSourceFile), action, emitOnlyDtsFiles);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Iterates over each source file to emit.
|
|
|
|
|
*/
|
|
|
|
|
export function forEachEmittedFile(host: EmitHost, sourceFiles: SourceFile[],
|
|
|
|
|
action: (emitFileNames: EmitFileNames, sourceFiles: SourceFile[], isBundledEmit: boolean, emitOnlyDtsFiles: boolean) => void,
|
|
|
|
|
emitOnlyDtsFiles?: boolean) {
|
|
|
|
|
const options = host.getCompilerOptions();
|
|
|
|
|
// Emit on each source file
|
|
|
|
|
if (options.outFile || options.out) {
|
|
|
|
|
onBundledEmit(host);
|
|
|
|
|
if (sourceFiles.length) {
|
|
|
|
|
const jsFilePath = options.outFile || options.out;
|
|
|
|
|
const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
|
|
|
|
|
const declarationFilePath = options.declaration ? removeFileExtension(jsFilePath) + ".d.ts" : undefined;
|
|
|
|
|
action({ jsFilePath, sourceMapFilePath, declarationFilePath }, sourceFiles, /*isBundledEmit*/true, emitOnlyDtsFiles);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
const sourceFiles = targetSourceFile === undefined ? getSourceFilesToEmit(host) : [targetSourceFile];
|
|
|
|
|
for (const sourceFile of sourceFiles) {
|
|
|
|
|
if (shouldEmitInDirectory(sourceFile, file => host.isSourceFileFromExternalLibrary(file))) {
|
|
|
|
|
onSingleFileEmit(host, sourceFile);
|
|
|
|
|
}
|
|
|
|
|
const options = host.getCompilerOptions();
|
|
|
|
|
const jsFilePath = getOwnEmitOutputFilePath(sourceFile, host, getOutputExtension(sourceFile, options));
|
|
|
|
|
const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
|
|
|
|
|
const declarationFilePath = !isSourceFileJavaScript(sourceFile) && (emitOnlyDtsFiles || options.declaration) ? getDeclarationEmitOutputFilePath(sourceFile, host) : undefined;
|
|
|
|
|
action({ jsFilePath, sourceMapFilePath, declarationFilePath }, [sourceFile], /*isBundledEmit*/false, emitOnlyDtsFiles);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function onSingleFileEmit(host: EmitHost, sourceFile: SourceFile) {
|
|
|
|
|
// JavaScript files are always LanguageVariant.JSX, as JSX syntax is allowed in .js files also.
|
|
|
|
|
// So for JavaScript files, '.jsx' is only emitted if the input was '.jsx', and JsxEmit.Preserve.
|
|
|
|
|
// For TypeScript, the only time to emit with a '.jsx' extension, is on JSX input, and JsxEmit.Preserve
|
|
|
|
|
let extension = ".js";
|
|
|
|
|
if (options.jsx === JsxEmit.Preserve) {
|
|
|
|
|
if (isSourceFileJavaScript(sourceFile)) {
|
|
|
|
|
if (fileExtensionIs(sourceFile.fileName, ".jsx")) {
|
|
|
|
|
extension = ".jsx";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (sourceFile.languageVariant === LanguageVariant.JSX) {
|
|
|
|
|
// TypeScript source file preserving JSX syntax
|
|
|
|
|
extension = ".jsx";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
const jsFilePath = getOwnEmitOutputFilePath(sourceFile, host, extension);
|
|
|
|
|
const declarationFilePath = !isSourceFileJavaScript(sourceFile) && (emitOnlyDtsFiles || options.declaration) ? getDeclarationEmitOutputFilePath(sourceFile, host) : undefined;
|
|
|
|
|
const emitFileNames: EmitFileNames = {
|
|
|
|
|
jsFilePath,
|
|
|
|
|
sourceMapFilePath: getSourceMapFilePath(jsFilePath, options),
|
|
|
|
|
declarationFilePath
|
|
|
|
|
};
|
|
|
|
|
action(emitFileNames, [sourceFile], /*isBundledEmit*/false, emitOnlyDtsFiles);
|
|
|
|
|
}
|
|
|
|
|
function getSourceMapFilePath(jsFilePath: string, options: CompilerOptions) {
|
|
|
|
|
return options.sourceMap ? jsFilePath + ".map" : undefined;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function onBundledEmit(host: EmitHost) {
|
|
|
|
|
// Can emit only sources that are not declaration file and are either non module code or module with
|
|
|
|
|
// --module or --target es6 specified. Files included by searching under node_modules are also not emitted.
|
|
|
|
|
const bundledSources = filter(getSourceFilesToEmit(host),
|
|
|
|
|
sourceFile => !isDeclarationFile(sourceFile) &&
|
|
|
|
|
!host.isSourceFileFromExternalLibrary(sourceFile) &&
|
|
|
|
|
(!isExternalModule(sourceFile) ||
|
|
|
|
|
!!getEmitModuleKind(options)));
|
|
|
|
|
if (bundledSources.length) {
|
|
|
|
|
const jsFilePath = options.outFile || options.out;
|
|
|
|
|
const emitFileNames: EmitFileNames = {
|
|
|
|
|
jsFilePath,
|
|
|
|
|
sourceMapFilePath: getSourceMapFilePath(jsFilePath, options),
|
|
|
|
|
declarationFilePath: options.declaration ? removeFileExtension(jsFilePath) + ".d.ts" : undefined
|
|
|
|
|
};
|
|
|
|
|
action(emitFileNames, bundledSources, /*isBundledEmit*/true, emitOnlyDtsFiles);
|
|
|
|
|
// JavaScript files are always LanguageVariant.JSX, as JSX syntax is allowed in .js files also.
|
|
|
|
|
// So for JavaScript files, '.jsx' is only emitted if the input was '.jsx', and JsxEmit.Preserve.
|
|
|
|
|
// For TypeScript, the only time to emit with a '.jsx' extension, is on JSX input, and JsxEmit.Preserve
|
|
|
|
|
function getOutputExtension(sourceFile: SourceFile, options: CompilerOptions): string {
|
|
|
|
|
if (options.jsx === JsxEmit.Preserve) {
|
|
|
|
|
if (isSourceFileJavaScript(sourceFile)) {
|
|
|
|
|
if (fileExtensionIs(sourceFile.fileName, ".jsx")) {
|
|
|
|
|
return ".jsx";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (sourceFile.languageVariant === LanguageVariant.JSX) {
|
|
|
|
|
// TypeScript source file preserving JSX syntax
|
|
|
|
|
return ".jsx";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return ".js";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getSourceFilePathInNewDir(sourceFile: SourceFile, host: EmitHost, newDirPath: string) {
|
|
|
|
|
|