mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Perform only emit on js file if no decl file change
This commit is contained in:
@@ -3992,14 +3992,26 @@
|
||||
"category": "Message",
|
||||
"code": 6371
|
||||
},
|
||||
"Project '{0}' is out of date because output to prepend from its dependency '{1}' has changed": {
|
||||
"Project '{0}' is out of date because output javascript and source map (if specified) of its dependency '{1}' has changed": {
|
||||
"category": "Message",
|
||||
"code": 6372
|
||||
},
|
||||
"Updating output of project '{0}'...": {
|
||||
"Updating output javascript and javascript source map (if specified) of project '{0}'...": {
|
||||
"category": "Message",
|
||||
"code": 6373
|
||||
},
|
||||
"A non-dry build would update timestamps for output of project '{0}'": {
|
||||
"category": "Message",
|
||||
"code": 6374
|
||||
},
|
||||
"A non-dry build would update output javascript and javascript source map (if specified) of project '{0}'": {
|
||||
"category": "Message",
|
||||
"code": 6375
|
||||
},
|
||||
"Cannot update output javascript and javascript source map (if specified) of project '{0}' because there was error reading file '{1}'": {
|
||||
"category": "Message",
|
||||
"code": 6376
|
||||
},
|
||||
|
||||
"The expected type comes from property '{0}' which is declared here on type '{1}'": {
|
||||
"category": "Message",
|
||||
|
||||
+135
-6
@@ -21,8 +21,9 @@ namespace ts {
|
||||
const sourceFiles = isArray(sourceFilesOrTargetSourceFile) ? sourceFilesOrTargetSourceFile : getSourceFilesToEmit(host, sourceFilesOrTargetSourceFile);
|
||||
const options = host.getCompilerOptions();
|
||||
if (options.outFile || options.out) {
|
||||
if (sourceFiles.length) {
|
||||
const bundle = createBundle(sourceFiles, host.getPrependNodes());
|
||||
const prepends = host.getPrependNodes();
|
||||
if (sourceFiles.length || prepends.length) {
|
||||
const bundle = createBundle(sourceFiles, prepends);
|
||||
const result = action(getOutputPathsFor(bundle, host, emitOnlyDtsFiles), bundle);
|
||||
if (result) {
|
||||
return result;
|
||||
@@ -104,7 +105,7 @@ namespace ts {
|
||||
|
||||
/*@internal*/
|
||||
// targetSourceFile is when users only want one file in entire project to be emitted. This is used in compileOnSave feature
|
||||
export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFile: SourceFile, emitOnlyDtsFiles?: boolean, transformers?: TransformerFactory<Bundle | SourceFile>[], declarationTransformers?: TransformerFactory<Bundle | SourceFile>[]): EmitResult {
|
||||
export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFile: SourceFile | undefined, emitOnlyDtsFiles?: boolean, transformers?: TransformerFactory<Bundle | SourceFile>[], declarationTransformers?: TransformerFactory<Bundle | SourceFile>[]): EmitResult {
|
||||
const compilerOptions = host.getCompilerOptions();
|
||||
const sourceMapDataList: SourceMapEmitResult[] | undefined = (compilerOptions.sourceMap || compilerOptions.inlineSourceMap || getAreDeclarationMapsEnabled(compilerOptions)) ? [] : undefined;
|
||||
const emittedFilesList: string[] | undefined = compilerOptions.listEmittedFiles ? [] : undefined;
|
||||
@@ -136,7 +137,7 @@ namespace ts {
|
||||
emitDeclarationFileOrBundle(sourceFileOrBundle, declarationFilePath, declarationMapPath, buildInfo && { sections: buildInfo.dts, sources: buildInfo.sources });
|
||||
// Write bundled offset information if applicable
|
||||
if (!emitOnlyDtsFiles && !emitSkipped && buildInfoPath) {
|
||||
writeFile(host, emitterDiagnostics, buildInfoPath, JSON.stringify(buildInfo, undefined, 2), /*writeByteOrderMark*/ false);
|
||||
writeFile(host, emitterDiagnostics, buildInfoPath, getBuildInfoText(buildInfo!), /*writeByteOrderMark*/ false);
|
||||
}
|
||||
|
||||
if (!emitSkipped && emittedFilesList) {
|
||||
@@ -409,6 +410,131 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getBuildInfoText(buildInfo: BuildInfo) {
|
||||
return JSON.stringify(buildInfo, undefined, 2);
|
||||
}
|
||||
|
||||
const notImplementedResolver: EmitResolver = {
|
||||
hasGlobalName: notImplemented,
|
||||
getReferencedExportContainer: notImplemented,
|
||||
getReferencedImportDeclaration: notImplemented,
|
||||
getReferencedDeclarationWithCollidingName: notImplemented,
|
||||
isDeclarationWithCollidingName: notImplemented,
|
||||
isValueAliasDeclaration: notImplemented,
|
||||
isReferencedAliasDeclaration: notImplemented,
|
||||
isTopLevelValueImportEqualsWithEntityName: notImplemented,
|
||||
getNodeCheckFlags: notImplemented,
|
||||
isDeclarationVisible: notImplemented,
|
||||
isLateBound: (_node): _node is LateBoundDeclaration => false,
|
||||
collectLinkedAliases: notImplemented,
|
||||
isImplementationOfOverload: notImplemented,
|
||||
isRequiredInitializedParameter: notImplemented,
|
||||
isOptionalUninitializedParameterProperty: notImplemented,
|
||||
isExpandoFunctionDeclaration: notImplemented,
|
||||
getPropertiesOfContainerFunction: notImplemented,
|
||||
createTypeOfDeclaration: notImplemented,
|
||||
createReturnTypeOfSignatureDeclaration: notImplemented,
|
||||
createTypeOfExpression: notImplemented,
|
||||
createLiteralConstValue: notImplemented,
|
||||
isSymbolAccessible: notImplemented,
|
||||
isEntityNameVisible: notImplemented,
|
||||
// Returns the constant value this property access resolves to: notImplemented, or 'undefined' for a non-constant
|
||||
getConstantValue: notImplemented,
|
||||
getReferencedValueDeclaration: notImplemented,
|
||||
getTypeReferenceSerializationKind: notImplemented,
|
||||
isOptionalParameter: notImplemented,
|
||||
moduleExportsSomeValue: notImplemented,
|
||||
isArgumentsLocalBinding: notImplemented,
|
||||
getExternalModuleFileFromDeclaration: notImplemented,
|
||||
getTypeReferenceDirectivesForEntityName: notImplemented,
|
||||
getTypeReferenceDirectivesForSymbol: notImplemented,
|
||||
isLiteralConstDeclaration: notImplemented,
|
||||
getJsxFactoryEntity: notImplemented,
|
||||
getAllAccessorDeclarations: notImplemented,
|
||||
getSymbolOfExternalModuleSpecifier: notImplemented,
|
||||
isBindingCapturedByNode: notImplemented,
|
||||
};
|
||||
|
||||
/*@internal*/
|
||||
/** File that isnt present resulting in error or output files */
|
||||
export type EmitUsingBuildInfoResult = string | ReadonlyArray<OutputFile>;
|
||||
|
||||
/*@internal*/
|
||||
export interface EmitUsingBuildInfoHost extends ModuleResolutionHost {
|
||||
getCurrentDirectory(): string;
|
||||
getCanonicalFileName(fileName: string): string;
|
||||
useCaseSensitiveFileNames(): boolean;
|
||||
getNewLine(): string;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export function emitUsingBuildInfo(config: ParsedCommandLine, host: EmitUsingBuildInfoHost, getCommandLine: (ref: ProjectReference) => ParsedCommandLine | undefined): EmitUsingBuildInfoResult {
|
||||
const { buildInfoPath, jsFilePath, sourceMapFilePath } = getOutputPathsForBundle(config.options, /*forceDtsPaths*/ false, config.projectReferences);
|
||||
const buildInfoText = host.readFile(Debug.assertDefined(buildInfoPath));
|
||||
if (!buildInfoText) return buildInfoPath!;
|
||||
const jsFileText = host.readFile(Debug.assertDefined(jsFilePath));
|
||||
if (!jsFileText) return jsFilePath!;
|
||||
const sourceMapText = sourceMapFilePath && host.readFile(sourceMapFilePath);
|
||||
// error if no source map or for now if inline sourcemap
|
||||
if ((sourceMapFilePath && !sourceMapText) || config.options.inlineSourceMap) return sourceMapFilePath || "inline sourcemap decoding";
|
||||
|
||||
const buildInfo = JSON.parse(buildInfoText) as BuildInfo;
|
||||
const ownPrependInput = createInputFiles(
|
||||
jsFileText,
|
||||
/*declarationText*/ undefined!,
|
||||
sourceMapFilePath,
|
||||
sourceMapText,
|
||||
/*declarationMapPath*/ undefined!,
|
||||
/*declarationMaptext*/ undefined!,
|
||||
jsFilePath,
|
||||
/*declarationPath*/ undefined,
|
||||
buildInfoPath,
|
||||
buildInfo,
|
||||
/*onlyOwnText*/ true
|
||||
);
|
||||
const optionsWithoutDeclaration = clone(config.options);
|
||||
optionsWithoutDeclaration.declaration = false;
|
||||
optionsWithoutDeclaration.composite = false;
|
||||
const outputFiles: OutputFile[] = [];
|
||||
const emitHost: EmitHost = {
|
||||
getPrependNodes: () => createPrependNodes(config.projectReferences, getCommandLine, f => host.readFile(f)). concat(ownPrependInput),
|
||||
getProjectReferences: () => config.projectReferences,
|
||||
getCanonicalFileName: host.getCanonicalFileName,
|
||||
getCommonSourceDirectory: () => buildInfo.commonSourceDirectory,
|
||||
getCompilerOptions: () => optionsWithoutDeclaration,
|
||||
getCurrentDirectory: () => host.getCurrentDirectory(),
|
||||
getNewLine: () => host.getNewLine(),
|
||||
getSourceFile: notImplemented,
|
||||
getSourceFileByPath: notImplemented,
|
||||
getSourceFiles: () => emptyArray,
|
||||
getLibFileFromReference: notImplemented,
|
||||
isSourceFileFromExternalLibrary: notImplemented,
|
||||
writeFile: (name, text, writeByteOrderMark) => {
|
||||
if (name === buildInfoPath) {
|
||||
// Add dts and sources build info since we are not touching that file
|
||||
const newBuildInfo = JSON.parse(text) as BuildInfo;
|
||||
newBuildInfo.dts = buildInfo.dts;
|
||||
newBuildInfo.sources = buildInfo.sources;
|
||||
text = getBuildInfoText(newBuildInfo);
|
||||
}
|
||||
outputFiles.push({ name, text, writeByteOrderMark });
|
||||
},
|
||||
isEmitBlocked: returnFalse,
|
||||
readFile: f => host.readFile(f),
|
||||
fileExists: f => host.fileExists(f),
|
||||
...(host.directoryExists ? { directoryExists: f => host.directoryExists!(f) } : {}),
|
||||
useCaseSensitiveFileNames: () => host.useCaseSensitiveFileNames(),
|
||||
};
|
||||
emitFiles(
|
||||
notImplementedResolver,
|
||||
emitHost,
|
||||
/*targetSourceFile*/ undefined,
|
||||
/*emitOnlyDtsFiles*/ false,
|
||||
getTransformers(optionsWithoutDeclaration)
|
||||
);
|
||||
return outputFiles;
|
||||
}
|
||||
|
||||
const enum PipelinePhase {
|
||||
Notification,
|
||||
Substitution,
|
||||
@@ -562,14 +688,17 @@ namespace ts {
|
||||
writeLine();
|
||||
const pos = getTextPosWithWriteLine();
|
||||
print(EmitHint.Unspecified, prepend, /*sourceFile*/ undefined);
|
||||
if (bundleFileInfo) bundleFileInfo.sections.push({ pos, end: writer.getTextPos(), kind: BundleFileSectionKind.Prepend, data: (prepend as UnparsedSource).fileName });
|
||||
if (bundleFileInfo) {
|
||||
if (prepend.oldFileOfCurrentEmit) bundleFileInfo.sections.push({ pos, end: writer.getTextPos(), kind: BundleFileSectionKind.Text });
|
||||
else bundleFileInfo.sections.push({ pos, end: writer.getTextPos(), kind: BundleFileSectionKind.Prepend, data: (prepend as UnparsedSource).fileName });
|
||||
}
|
||||
}
|
||||
|
||||
const pos = getTextPosWithWriteLine();
|
||||
for (const sourceFile of bundle.sourceFiles) {
|
||||
print(EmitHint.SourceFile, sourceFile, sourceFile);
|
||||
}
|
||||
if (bundleFileInfo) {
|
||||
if (bundleFileInfo && bundle.sourceFiles.length) {
|
||||
bundleFileInfo.sections.push({ pos, end: writer.getTextPos(), kind: BundleFileSectionKind.Text });
|
||||
// Store prologues
|
||||
const prologues = getPrologueDirectivesFromBundledSourceFiles(bundle);
|
||||
|
||||
+27
-10
@@ -2666,6 +2666,7 @@ namespace ts {
|
||||
let texts: UnparsedSourceText[] | undefined;
|
||||
if (!isString(textOrInputFiles)) {
|
||||
Debug.assert(mapPathOrType === "js" || mapPathOrType === "dts");
|
||||
node.oldFileOfCurrentEmit = textOrInputFiles.oldFileOfCurrentEmit;
|
||||
node.fileName = (mapPathOrType === "js" ? textOrInputFiles.javascriptPath : textOrInputFiles.declarationPath) || "";
|
||||
node.sourceMapPath = mapPathOrType === "js" ? textOrInputFiles.javascriptMapPath : textOrInputFiles.declarationMapPath;
|
||||
Object.defineProperties(node, {
|
||||
@@ -2676,6 +2677,7 @@ namespace ts {
|
||||
if (textOrInputFiles.buildInfo) {
|
||||
const sections = mapPathOrType === "js" ? textOrInputFiles.buildInfo.js : textOrInputFiles.buildInfo.dts;
|
||||
for (const section of sections) {
|
||||
if (textOrInputFiles.oldFileOfCurrentEmit && section.kind !== BundleFileSectionKind.Text) continue;
|
||||
switch (section.kind) {
|
||||
case BundleFileSectionKind.Prologue:
|
||||
(prologues || (prologues = [])).push(createUnparsedNode(section, node) as UnparsedPrologue);
|
||||
@@ -2766,7 +2768,12 @@ namespace ts {
|
||||
javascriptMapPath: string | undefined,
|
||||
javascriptMapText: string | undefined,
|
||||
declarationMapPath: string | undefined,
|
||||
declarationMapText: string | undefined
|
||||
declarationMapText: string | undefined,
|
||||
javascriptPath: string | undefined,
|
||||
declarationPath: string | undefined,
|
||||
buildInfoPath?: string | undefined,
|
||||
buildInfo?: BuildInfo,
|
||||
oldFileOfCurrentEmit?: boolean
|
||||
): InputFiles;
|
||||
export function createInputFiles(
|
||||
javascriptTextOrReadFileText: string | ((path: string) => string | undefined),
|
||||
@@ -2774,17 +2781,14 @@ namespace ts {
|
||||
javascriptMapPath?: string,
|
||||
javascriptMapTextOrDeclarationPath?: string,
|
||||
declarationMapPath?: string,
|
||||
declarationMapTextOrBuildInfoPath?: string
|
||||
declarationMapTextOrBuildInfoPath?: string,
|
||||
javascriptPath?: string | undefined,
|
||||
declarationPath?: string | undefined,
|
||||
buildInfoPath?: string | undefined,
|
||||
buildInfo?: BuildInfo,
|
||||
oldFileOfCurrentEmit?: boolean
|
||||
): InputFiles {
|
||||
const node = <InputFiles>createNode(SyntaxKind.InputFiles);
|
||||
let buildInfo: BuildInfo | false;
|
||||
const getBuildInfo = (getText: () => string | undefined) => {
|
||||
if (buildInfo === undefined) {
|
||||
const result = getText();
|
||||
buildInfo = result !== undefined ? JSON.parse(result) as BuildInfo : false;
|
||||
}
|
||||
return buildInfo || undefined;
|
||||
};
|
||||
if (!isString(javascriptTextOrReadFileText)) {
|
||||
const cache = createMap<string | false>();
|
||||
const textGetter = (path: string | undefined) => {
|
||||
@@ -2800,6 +2804,14 @@ namespace ts {
|
||||
const result = textGetter(path);
|
||||
return result !== undefined ? result : `/* Input file ${path} was missing */\r\n`;
|
||||
};
|
||||
let buildInfo: BuildInfo | false;
|
||||
const getBuildInfo = (getText: () => string | undefined) => {
|
||||
if (buildInfo === undefined) {
|
||||
const result = getText();
|
||||
buildInfo = result !== undefined ? JSON.parse(result) as BuildInfo : false;
|
||||
}
|
||||
return buildInfo || undefined;
|
||||
};
|
||||
node.javascriptPath = declarationTextOrJavascriptPath;
|
||||
node.javascriptMapPath = javascriptMapPath;
|
||||
node.declarationPath = Debug.assertDefined(javascriptMapTextOrDeclarationPath);
|
||||
@@ -2820,6 +2832,11 @@ namespace ts {
|
||||
node.declarationText = declarationTextOrJavascriptPath;
|
||||
node.declarationMapPath = declarationMapPath;
|
||||
node.declarationMapText = declarationMapTextOrBuildInfoPath;
|
||||
node.javascriptPath = javascriptPath;
|
||||
node.declarationPath = declarationPath,
|
||||
node.buildInfoPath = buildInfoPath;
|
||||
node.buildInfo = buildInfo;
|
||||
node.oldFileOfCurrentEmit = oldFileOfCurrentEmit;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
+29
-24
@@ -1443,30 +1443,16 @@ namespace ts {
|
||||
return projectReferences;
|
||||
}
|
||||
|
||||
function getPrependNodes(): InputFiles[] {
|
||||
if (!projectReferences) {
|
||||
return emptyArray;
|
||||
}
|
||||
|
||||
const nodes: InputFiles[] = [];
|
||||
for (let i = 0; i < projectReferences.length; i++) {
|
||||
const ref = projectReferences[i];
|
||||
const resolvedRefOpts = resolvedProjectReferences![i]!.commandLine;
|
||||
if (ref.prepend && resolvedRefOpts && resolvedRefOpts.options) {
|
||||
const out = resolvedRefOpts.options.outFile || resolvedRefOpts.options.out;
|
||||
// Upstream project didn't have outFile set -- skip (error will have been issued earlier)
|
||||
if (!out) continue;
|
||||
|
||||
const { jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, buildInfoPath } = getOutputPathsForBundle(resolvedRefOpts.options, /*forceDtsPaths*/ true, resolvedRefOpts.projectReferences);
|
||||
const node = createInputFiles(fileName => {
|
||||
const path = toPath(fileName);
|
||||
const sourceFile = getSourceFileByPath(path);
|
||||
return sourceFile ? sourceFile.text : filesByName.has(path) ? undefined : host.readFile(path);
|
||||
}, jsFilePath! , sourceMapFilePath, declarationFilePath! , declarationMapPath, buildInfoPath);
|
||||
nodes.push(node);
|
||||
function getPrependNodes() {
|
||||
return createPrependNodes(
|
||||
projectReferences,
|
||||
(_ref, index) => resolvedProjectReferences![index]!.commandLine,
|
||||
fileName => {
|
||||
const path = toPath(fileName);
|
||||
const sourceFile = getSourceFileByPath(path);
|
||||
return sourceFile ? sourceFile.text : filesByName.has(path) ? undefined : host.readFile(path);
|
||||
}
|
||||
}
|
||||
return nodes;
|
||||
);
|
||||
}
|
||||
|
||||
function isSourceFileFromExternalLibrary(file: SourceFile): boolean {
|
||||
@@ -1563,7 +1549,7 @@ namespace ts {
|
||||
const emitResult = emitFiles(
|
||||
emitResolver,
|
||||
getEmitHost(writeFileCallback),
|
||||
sourceFile!, // TODO: GH#18217
|
||||
sourceFile,
|
||||
emitOnlyDtsFiles,
|
||||
transformers,
|
||||
customTransformers && customTransformers.afterDeclarations
|
||||
@@ -3141,6 +3127,25 @@ namespace ts {
|
||||
fileExists(fileName: string): boolean;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function createPrependNodes(projectReferences: ReadonlyArray<ProjectReference> | undefined, getCommandLine: (ref: ProjectReference, index: number) => ParsedCommandLine | undefined, readFile: (path: string) => string | undefined) {
|
||||
if (!projectReferences) return emptyArray;
|
||||
let nodes: InputFiles[] | undefined;
|
||||
for (let i = 0; i < projectReferences.length; i++) {
|
||||
const ref = projectReferences[i];
|
||||
const resolvedRefOpts = getCommandLine(ref, i);
|
||||
if (ref.prepend && resolvedRefOpts && resolvedRefOpts.options) {
|
||||
const out = resolvedRefOpts.options.outFile || resolvedRefOpts.options.out;
|
||||
// Upstream project didn't have outFile set -- skip (error will have been issued earlier)
|
||||
if (!out) continue;
|
||||
|
||||
const { jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, buildInfoPath } = getOutputPathsForBundle(resolvedRefOpts.options, /*forceDtsPaths*/ true, resolvedRefOpts.projectReferences);
|
||||
const node = createInputFiles(readFile, jsFilePath!, sourceMapFilePath, declarationFilePath!, declarationMapPath, buildInfoPath);
|
||||
(nodes || (nodes = [])).push(node);
|
||||
}
|
||||
}
|
||||
return nodes || emptyArray;
|
||||
}
|
||||
/**
|
||||
* Returns the target config filename of a project reference.
|
||||
* Note: The file might not exist.
|
||||
|
||||
+62
-20
@@ -1007,13 +1007,9 @@ namespace ts {
|
||||
return;
|
||||
}
|
||||
|
||||
//if (status.type === UpToDateStatusType.OutOfDateWithPrepend) {
|
||||
// // Fake that files have been built by manipulating prepend and existing output
|
||||
// //updateOutputTimestamps(proj);
|
||||
// return;
|
||||
//}
|
||||
|
||||
const buildResult = buildSingleProject(resolved);
|
||||
const buildResult = status.type === UpToDateStatusType.OutOfDateWithPrepend ?
|
||||
updateBundle(resolved) : // Fake that files have been built by manipulating prepend and existing output
|
||||
buildSingleProject(resolved); // Actual build
|
||||
if (buildResult & BuildResultFlags.AnyErrors) return;
|
||||
|
||||
const { referencingProjectsMap, buildQueue } = getGlobalDependencyGraph();
|
||||
@@ -1109,8 +1105,7 @@ namespace ts {
|
||||
|
||||
if (options.verbose) reportStatus(Diagnostics.Building_project_0, proj);
|
||||
|
||||
let resultFlags = BuildResultFlags.None;
|
||||
resultFlags |= BuildResultFlags.DeclarationOutputUnchanged;
|
||||
let resultFlags = BuildResultFlags.DeclarationOutputUnchanged;
|
||||
|
||||
const configFile = parseConfigFile(proj);
|
||||
if (!configFile) {
|
||||
@@ -1136,7 +1131,6 @@ namespace ts {
|
||||
configFile.errors,
|
||||
configFile.projectReferences
|
||||
);
|
||||
projectCompilerOptions = baseCompilerOptions;
|
||||
|
||||
// Don't emit anything in the presence of syntactic errors or options diagnostics
|
||||
const syntaxDiagnostics = [
|
||||
@@ -1208,6 +1202,7 @@ namespace ts {
|
||||
diagnostics.removeKey(proj);
|
||||
projectStatus.setValue(proj, status);
|
||||
afterProgramCreate(proj, program);
|
||||
projectCompilerOptions = baseCompilerOptions;
|
||||
return resultFlags;
|
||||
|
||||
function buildErrors(diagnostics: ReadonlyArray<Diagnostic>, errorFlags: BuildResultFlags, errorType: string) {
|
||||
@@ -1215,6 +1210,7 @@ namespace ts {
|
||||
reportAndStoreErrors(proj, diagnostics);
|
||||
projectStatus.setValue(proj, { type: UpToDateStatusType.Unbuildable, reason: `${errorType} errors` });
|
||||
afterProgramCreate(proj, program);
|
||||
projectCompilerOptions = baseCompilerOptions;
|
||||
return resultFlags;
|
||||
}
|
||||
}
|
||||
@@ -1229,9 +1225,60 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function updateBundle(proj: ResolvedConfigFileName): BuildResultFlags {
|
||||
if (options.dry) {
|
||||
reportStatus(Diagnostics.A_non_dry_build_would_update_output_javascript_and_javascript_source_map_if_specified_of_project_0, proj);
|
||||
return BuildResultFlags.Success;
|
||||
}
|
||||
|
||||
if (options.verbose) reportStatus(Diagnostics.Updating_output_javascript_and_javascript_source_map_if_specified_of_project_0, proj);
|
||||
|
||||
// Update js, and source map
|
||||
const config = Debug.assertDefined(parseConfigFile(proj));
|
||||
projectCompilerOptions = config.options;
|
||||
const outputFiles = emitUsingBuildInfo(
|
||||
config,
|
||||
compilerHost,
|
||||
ref => parseConfigFile(resolveProjectName(ref.path)));
|
||||
if (isString(outputFiles)) {
|
||||
reportStatus(Diagnostics.Cannot_update_output_javascript_and_javascript_source_map_if_specified_of_project_0_because_there_was_error_reading_file_1, proj, relName(outputFiles));
|
||||
return buildSingleProject(proj);
|
||||
}
|
||||
|
||||
// Actual Emit
|
||||
Debug.assert(!!outputFiles.length);
|
||||
const emitterDiagnostics = createDiagnosticCollection();
|
||||
const emittedOutputs = createFileMap<true>(toPath as ToPath);
|
||||
outputFiles.forEach(({ name, text, writeByteOrderMark }) => {
|
||||
emittedOutputs.setValue(name, true);
|
||||
writeFile(compilerHost, emitterDiagnostics, name, text, writeByteOrderMark);
|
||||
});
|
||||
const emitDiagnostics = emitterDiagnostics.getDiagnostics();
|
||||
if (emitDiagnostics.length) {
|
||||
reportAndStoreErrors(proj, emitDiagnostics);
|
||||
projectStatus.setValue(proj, { type: UpToDateStatusType.Unbuildable, reason: "Emit errors" });
|
||||
projectCompilerOptions = baseCompilerOptions;
|
||||
return BuildResultFlags.DeclarationOutputUnchanged | BuildResultFlags.EmitErrors;
|
||||
}
|
||||
|
||||
// Update timestamps for dts
|
||||
const newestDeclarationFileContentChangedTime = updateOutputTimestampsWorker(config, minimumDate, Diagnostics.Updating_unchanged_output_timestamps_of_project_0, emittedOutputs);
|
||||
|
||||
const status: UpToDateStatus = {
|
||||
type: UpToDateStatusType.UpToDate,
|
||||
newestDeclarationFileContentChangedTime,
|
||||
oldestOutputFileName: outputFiles[0].name
|
||||
};
|
||||
|
||||
diagnostics.removeKey(proj);
|
||||
projectStatus.setValue(proj, status);
|
||||
projectCompilerOptions = baseCompilerOptions;
|
||||
return BuildResultFlags.DeclarationOutputUnchanged;
|
||||
}
|
||||
|
||||
function updateOutputTimestamps(proj: ParsedCommandLine) {
|
||||
if (options.dry) {
|
||||
return reportStatus(Diagnostics.A_non_dry_build_would_build_project_0, proj.options.configFilePath!);
|
||||
return reportStatus(Diagnostics.A_non_dry_build_would_update_timestamps_for_output_of_project_0, proj.options.configFilePath!);
|
||||
}
|
||||
const priorNewestUpdateTime = updateOutputTimestampsWorker(proj, minimumDate, Diagnostics.Updating_output_timestamps_of_project_0);
|
||||
projectStatus.setValue(proj.options.configFilePath as ResolvedConfigFilePath, { type: UpToDateStatusType.UpToDate, newestDeclarationFileContentChangedTime: priorNewestUpdateTime } as UpToDateStatus);
|
||||
@@ -1354,13 +1401,6 @@ namespace ts {
|
||||
continue;
|
||||
}
|
||||
|
||||
//if (status.type === UpToDateStatusType.OutOfDateWithPrepend && !options.force) {
|
||||
// reportAndStoreErrors(next, errors);
|
||||
// // Fake that files have been built by manipulating prepend and existing output
|
||||
// // updateOutputTimestamps(proj);
|
||||
// continue;
|
||||
//}
|
||||
|
||||
if (status.type === UpToDateStatusType.UpstreamBlocked) {
|
||||
reportAndStoreErrors(next, errors);
|
||||
if (options.verbose) reportStatus(Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_has_errors, projName, status.upstreamProjectName);
|
||||
@@ -1373,7 +1413,9 @@ namespace ts {
|
||||
continue;
|
||||
}
|
||||
|
||||
const buildResult = buildSingleProject(next);
|
||||
const buildResult = status.type === UpToDateStatusType.OutOfDateWithPrepend && !options.force ?
|
||||
updateBundle(next) : // Fake that files have been built by manipulating prepend and existing output
|
||||
buildSingleProject(next); // Actual build
|
||||
anyFailed = anyFailed || !!(buildResult & BuildResultFlags.AnyErrors);
|
||||
}
|
||||
reportErrorSummary();
|
||||
@@ -1484,7 +1526,7 @@ namespace ts {
|
||||
// Don't report anything for "up to date because it was already built" -- too verbose
|
||||
break;
|
||||
case UpToDateStatusType.OutOfDateWithPrepend:
|
||||
return formatMessage(Diagnostics.Project_0_is_out_of_date_because_output_to_prepend_from_its_dependency_1_has_changed,
|
||||
return formatMessage(Diagnostics.Project_0_is_out_of_date_because_output_javascript_and_source_map_if_specified_of_its_dependency_1_has_changed,
|
||||
relName(configFileName),
|
||||
relName(status.newerProjectName));
|
||||
case UpToDateStatusType.UpToDateWithUpstreamTypes:
|
||||
|
||||
@@ -2775,8 +2775,9 @@ namespace ts {
|
||||
declarationText: string;
|
||||
declarationMapPath?: string;
|
||||
declarationMapText?: string;
|
||||
buildInfoPath?: string;
|
||||
/*@internal*/ buildInfoPath?: string;
|
||||
/*@internal*/ buildInfo?: BuildInfo;
|
||||
/*@internal*/ oldFileOfCurrentEmit?: boolean;
|
||||
}
|
||||
|
||||
export interface UnparsedSource extends Node {
|
||||
@@ -2785,13 +2786,17 @@ namespace ts {
|
||||
text: string;
|
||||
prologues: ReadonlyArray<UnparsedPrologue>;
|
||||
helpers: ReadonlyArray<UnscopedEmitHelpers> | undefined;
|
||||
|
||||
// References and noDefaultLibAre Dts only
|
||||
referencedFiles: ReadonlyArray<FileReference>;
|
||||
typeReferenceDirectives: ReadonlyArray<string> | undefined;
|
||||
libReferenceDirectives: ReadonlyArray<FileReference>;
|
||||
hasNoDefaultLib?: boolean;
|
||||
|
||||
sourceMapPath?: string;
|
||||
sourceMapText?: string;
|
||||
texts: ReadonlyArray<UnparsedSourceText>;
|
||||
/*@internal*/ oldFileOfCurrentEmit?: boolean;
|
||||
/*@internal*/ parsedSourceMap?: RawSourceMap | false | undefined;
|
||||
// Adding this to satisfy services, fix later
|
||||
/*@internal*/
|
||||
|
||||
@@ -241,38 +241,7 @@ Mismatch Actual: ${JSON.stringify(mapDefined(arrayFrom(actualReadFileMap.entries
|
||||
|
||||
incrementalBuild(
|
||||
"incremental declaration doesnt change",
|
||||
[
|
||||
// Configs
|
||||
sources[project.first][source.config],
|
||||
sources[project.second][source.config],
|
||||
sources[project.third][source.config],
|
||||
|
||||
// Source files
|
||||
...sources[project.first][source.ts],
|
||||
...sources[project.third][source.ts],
|
||||
|
||||
// Additional source Files
|
||||
...(additionalSourceFiles || emptyArray),
|
||||
|
||||
// outputs
|
||||
...outputFiles[project.first],
|
||||
...outputFiles[project.second],
|
||||
outputFiles[project.third][ext.dts],
|
||||
],
|
||||
fs => appendFileContent(fs, relSources[project.first][source.ts][part.one], "console.log(s);"),
|
||||
[
|
||||
getExpectedDiagnosticForProjectsInBuild(relSources[project.first][source.config], relSources[project.second][source.config], relSources[project.third][source.config]),
|
||||
[Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2, relSources[project.first][source.config], relOutputFiles[project.first][ext.js], relSources[project.first][source.ts][part.one]],
|
||||
[Diagnostics.Building_project_0, sources[project.first][source.config]],
|
||||
[Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, relSources[project.second][source.config], relSources[project.second][source.ts][part.one], relOutputFiles[project.second][ext.js]],
|
||||
[Diagnostics.Project_0_is_out_of_date_because_output_to_prepend_from_its_dependency_1_has_changed, relSources[project.third][source.config], "src/first"],
|
||||
[Diagnostics.Building_project_0, sources[project.third][source.config]]
|
||||
]
|
||||
);
|
||||
|
||||
if (modifyAgainFs) {
|
||||
incrementalBuild(
|
||||
"incremental headers change",
|
||||
withoutBuildInfo ?
|
||||
[
|
||||
// Configs
|
||||
sources[project.first][source.config],
|
||||
@@ -290,15 +259,122 @@ Mismatch Actual: ${JSON.stringify(mapDefined(arrayFrom(actualReadFileMap.entries
|
||||
...outputFiles[project.first],
|
||||
...outputFiles[project.second],
|
||||
outputFiles[project.third][ext.dts],
|
||||
|
||||
// To prepend:: checked to see if we can do prepend manipulation
|
||||
outputFiles[project.third][ext.buildinfo],
|
||||
] :
|
||||
[
|
||||
// Configs
|
||||
sources[project.first][source.config],
|
||||
sources[project.second][source.config],
|
||||
sources[project.third][source.config],
|
||||
|
||||
// Source files
|
||||
...sources[project.first][source.ts],
|
||||
|
||||
// Additional source Files
|
||||
...(additionalSourceFiles && additionalSourceFiles.length === 3 ? [additionalSourceFiles[project.first]] : emptyArray),
|
||||
|
||||
// outputs without d.ts since we just update js
|
||||
outputFiles[project.first][ext.js],
|
||||
outputFiles[project.first][ext.jsmap],
|
||||
outputFiles[project.first][ext.dts],
|
||||
outputFiles[project.first][ext.buildinfo],
|
||||
outputFiles[project.second][ext.js],
|
||||
outputFiles[project.second][ext.jsmap],
|
||||
outputFiles[project.second][ext.buildinfo],
|
||||
|
||||
// To prepend::
|
||||
outputFiles[project.third][ext.buildinfo],
|
||||
outputFiles[project.third][ext.js],
|
||||
outputFiles[project.third][ext.jsmap]
|
||||
],
|
||||
fs => appendFileContent(fs, relSources[project.first][source.ts][part.one], "console.log(s);"),
|
||||
[
|
||||
getExpectedDiagnosticForProjectsInBuild(relSources[project.first][source.config], relSources[project.second][source.config], relSources[project.third][source.config]),
|
||||
[Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2, relSources[project.first][source.config], relOutputFiles[project.first][ext.js], relSources[project.first][source.ts][part.one]],
|
||||
[Diagnostics.Building_project_0, sources[project.first][source.config]],
|
||||
[Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, relSources[project.second][source.config], relSources[project.second][source.ts][part.one], relOutputFiles[project.second][ext.js]],
|
||||
[Diagnostics.Project_0_is_out_of_date_because_output_javascript_and_source_map_if_specified_of_its_dependency_1_has_changed, relSources[project.third][source.config], "src/first"],
|
||||
[Diagnostics.Updating_output_javascript_and_javascript_source_map_if_specified_of_project_0, sources[project.third][source.config]],
|
||||
...<ReadonlyArray<fakes.ExpectedDiagnostic>>(!withoutBuildInfo ?
|
||||
[
|
||||
[Diagnostics.Updating_unchanged_output_timestamps_of_project_0, sources[project.third][source.config]]
|
||||
] :
|
||||
[
|
||||
[Diagnostics.Cannot_update_output_javascript_and_javascript_source_map_if_specified_of_project_0_because_there_was_error_reading_file_1, sources[project.third][source.config], relOutputFiles[project.third][ext.buildinfo]],
|
||||
[Diagnostics.Building_project_0, sources[project.third][source.config]]
|
||||
])
|
||||
]
|
||||
);
|
||||
|
||||
if (modifyAgainFs) {
|
||||
incrementalBuild(
|
||||
"incremental headers change",
|
||||
withoutBuildInfo ?
|
||||
[
|
||||
// Configs
|
||||
sources[project.first][source.config],
|
||||
sources[project.second][source.config],
|
||||
sources[project.third][source.config],
|
||||
|
||||
// Source files
|
||||
...sources[project.first][source.ts],
|
||||
...sources[project.third][source.ts],
|
||||
|
||||
// Additional source Files
|
||||
...(additionalSourceFiles || emptyArray),
|
||||
|
||||
// outputs
|
||||
...outputFiles[project.first],
|
||||
...outputFiles[project.second],
|
||||
outputFiles[project.third][ext.dts],
|
||||
|
||||
// To prepend:: checked to see if we can do prepend manipulation
|
||||
outputFiles[project.third][ext.buildinfo],
|
||||
] :
|
||||
[
|
||||
// Configs
|
||||
sources[project.first][source.config],
|
||||
sources[project.second][source.config],
|
||||
sources[project.third][source.config],
|
||||
|
||||
// Source files
|
||||
...sources[project.first][source.ts],
|
||||
|
||||
// Additional source Files
|
||||
...(additionalSourceFiles || emptyArray),
|
||||
|
||||
// outputs without d.ts since we just update js
|
||||
outputFiles[project.first][ext.js],
|
||||
outputFiles[project.first][ext.jsmap],
|
||||
outputFiles[project.first][ext.dts],
|
||||
outputFiles[project.first][ext.buildinfo],
|
||||
outputFiles[project.second][ext.js],
|
||||
outputFiles[project.second][ext.jsmap],
|
||||
outputFiles[project.second][ext.buildinfo],
|
||||
|
||||
// To prepend::
|
||||
outputFiles[project.third][ext.buildinfo],
|
||||
outputFiles[project.third][ext.js],
|
||||
outputFiles[project.third][ext.jsmap]
|
||||
],
|
||||
fs => modifyAgainFs(fs),
|
||||
[
|
||||
getExpectedDiagnosticForProjectsInBuild(relSources[project.first][source.config], relSources[project.second][source.config], relSources[project.third][source.config]),
|
||||
[Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2, relSources[project.first][source.config], relOutputFiles[project.first][ext.js], relSources[project.first][source.ts][part.one]],
|
||||
[Diagnostics.Building_project_0, sources[project.first][source.config]],
|
||||
[Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, relSources[project.second][source.config], relSources[project.second][source.ts][part.one], relOutputFiles[project.second][ext.js]],
|
||||
[Diagnostics.Project_0_is_out_of_date_because_output_to_prepend_from_its_dependency_1_has_changed, relSources[project.third][source.config], "src/first"],
|
||||
[Diagnostics.Building_project_0, sources[project.third][source.config]]
|
||||
[Diagnostics.Project_0_is_out_of_date_because_output_javascript_and_source_map_if_specified_of_its_dependency_1_has_changed, relSources[project.third][source.config], "src/first"],
|
||||
[Diagnostics.Updating_output_javascript_and_javascript_source_map_if_specified_of_project_0, sources[project.third][source.config]],
|
||||
...<ReadonlyArray<fakes.ExpectedDiagnostic>>(!withoutBuildInfo ?
|
||||
[
|
||||
[Diagnostics.Updating_unchanged_output_timestamps_of_project_0, sources[project.third][source.config]]
|
||||
] :
|
||||
[
|
||||
[Diagnostics.Cannot_update_output_javascript_and_javascript_source_map_if_specified_of_project_0_because_there_was_error_reading_file_1, sources[project.third][source.config], relOutputFiles[project.third][ext.buildinfo]],
|
||||
[Diagnostics.Building_project_0, sources[project.third][source.config]]
|
||||
])
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user