Removing some unnecessary methods from host and function parameters (#51499)

This commit is contained in:
Sheetal Nandi
2022-11-15 17:34:58 -08:00
committed by GitHub
parent 4d53a1f8f1
commit 2f2a17ad0b
10 changed files with 71 additions and 119 deletions

View File

@@ -9,7 +9,7 @@ import {
EmitAndSemanticDiagnosticsBuilderProgram, EmitOnly, EmitResult, emitSkippedWithNoDiagnostics, emptyArray,
ensurePathIsNonModuleName, filterSemanticDiagnostics, forEach, forEachEntry, forEachKey, generateDjb2Hash,
GetCanonicalFileName, getDirectoryPath, getEmitDeclarations, getNormalizedAbsolutePath, getOptionsNameMap,
getOwnKeys, getRelativePathFromDirectory, getTsBuildInfoEmitOutputFilePath, handleNoEmitOptions, isArray,
getOwnKeys, getRelativePathFromDirectory, getTsBuildInfoEmitOutputFilePath, handleNoEmitOptions, HostForComputeHash, isArray,
isDeclarationFileName, isJsonSourceFile, isNumber, isString, map, mapDefined, maybeBind, noop, notImplemented,
outFile, Path, Program, ProjectReference, ReadBuildProgramHost, ReadonlyCollection,
returnFalse, returnUndefined, SemanticDiagnosticsBuilderProgram, skipTypeChecking, some, SourceFile,
@@ -220,8 +220,8 @@ function hasSameKeys(map1: ReadonlyCollection<string> | undefined, map2: Readonl
/**
* Create the state so that we can iterate on changedFiles/affected files
*/
function createBuilderProgramState(newProgram: Program, getCanonicalFileName: GetCanonicalFileName, oldState: Readonly<ReusableBuilderProgramState> | undefined, disableUseFileVersionAsSignature: boolean | undefined): BuilderProgramState {
const state = BuilderState.create(newProgram, getCanonicalFileName, oldState, disableUseFileVersionAsSignature) as BuilderProgramState;
function createBuilderProgramState(newProgram: Program, oldState: Readonly<ReusableBuilderProgramState> | undefined, disableUseFileVersionAsSignature: boolean | undefined): BuilderProgramState {
const state = BuilderState.create(newProgram, oldState, disableUseFileVersionAsSignature) as BuilderProgramState;
state.program = newProgram;
const compilerOptions = newProgram.getCompilerOptions();
state.compilerOptions = compilerOptions;
@@ -297,7 +297,7 @@ function createBuilderProgramState(newProgram: Program, getCanonicalFileName: Ge
// Unchanged file copy diagnostics
const diagnostics = oldState!.semanticDiagnosticsPerFile!.get(sourceFilePath);
if (diagnostics) {
state.semanticDiagnosticsPerFile!.set(sourceFilePath, oldState!.hasReusableDiagnostic ? convertToDiagnostics(diagnostics as readonly ReusableDiagnostic[], newProgram, getCanonicalFileName) : diagnostics as readonly Diagnostic[]);
state.semanticDiagnosticsPerFile!.set(sourceFilePath, oldState!.hasReusableDiagnostic ? convertToDiagnostics(diagnostics as readonly ReusableDiagnostic[], newProgram) : diagnostics as readonly Diagnostic[]);
if (!state.semanticDiagnosticsFromOldState) {
state.semanticDiagnosticsFromOldState = new Set();
}
@@ -381,9 +381,10 @@ function getEmitSignatureFromOldSignature(options: CompilerOptions, oldOptions:
isString(oldEmitSignature) ? [oldEmitSignature] : oldEmitSignature[0];
}
function convertToDiagnostics(diagnostics: readonly ReusableDiagnostic[], newProgram: Program, getCanonicalFileName: GetCanonicalFileName): readonly Diagnostic[] {
function convertToDiagnostics(diagnostics: readonly ReusableDiagnostic[], newProgram: Program): readonly Diagnostic[] {
if (!diagnostics.length) return emptyArray;
const buildInfoDirectory = getDirectoryPath(getNormalizedAbsolutePath(getTsBuildInfoEmitOutputFilePath(newProgram.getCompilerOptions())!, newProgram.getCurrentDirectory()));
let buildInfoDirectory: string | undefined;
let getCanonicalFileName: GetCanonicalFileName | undefined;
return diagnostics.map(diagnostic => {
const result: Diagnostic = convertToDiagnosticRelatedInformation(diagnostic, newProgram, toPath);
result.reportsUnnecessary = diagnostic.reportsUnnecessary;
@@ -400,7 +401,8 @@ function convertToDiagnostics(diagnostics: readonly ReusableDiagnostic[], newPro
});
function toPath(path: string) {
return ts.toPath(path, buildInfoDirectory, getCanonicalFileName);
buildInfoDirectory ??= getDirectoryPath(getNormalizedAbsolutePath(getTsBuildInfoEmitOutputFilePath(newProgram.getCompilerOptions())!, newProgram.getCurrentDirectory()));
return ts.toPath(path, buildInfoDirectory, getCanonicalFileName ??= createGetCanonicalFileName(newProgram.useCaseSensitiveFileNames()));
}
}
@@ -463,8 +465,6 @@ function assertSourceFileOkWithoutNextAffectedCall(state: BuilderProgramState, s
function getNextAffectedFile(
state: BuilderProgramState,
cancellationToken: CancellationToken | undefined,
computeHash: BuilderState.ComputeHash,
getCanonicalFileName: GetCanonicalFileName,
host: BuilderProgramHost
): SourceFile | Program | undefined {
while (true) {
@@ -482,8 +482,6 @@ function getNextAffectedFile(
state,
affectedFile,
cancellationToken,
computeHash,
getCanonicalFileName,
host
);
return affectedFile;
@@ -522,8 +520,7 @@ function getNextAffectedFile(
program,
nextKey.value,
cancellationToken,
computeHash,
getCanonicalFileName,
host,
);
state.currentChangedFilePath = nextKey.value;
state.affectedFilesIndex = 0;
@@ -581,8 +578,6 @@ function handleDtsMayChangeOfAffectedFile(
state: BuilderProgramState,
affectedFile: SourceFile,
cancellationToken: CancellationToken | undefined,
computeHash: BuilderState.ComputeHash,
getCanonicalFileName: GetCanonicalFileName,
host: BuilderProgramHost,
) {
removeSemanticDiagnosticsOf(state, affectedFile.resolvedPath);
@@ -598,8 +593,7 @@ function handleDtsMayChangeOfAffectedFile(
Debug.checkDefined(state.program),
affectedFile,
cancellationToken,
computeHash,
getCanonicalFileName,
host,
);
return;
}
@@ -608,8 +602,6 @@ function handleDtsMayChangeOfAffectedFile(
state,
affectedFile,
cancellationToken,
computeHash,
getCanonicalFileName,
host,
);
}
@@ -622,8 +614,6 @@ function handleDtsMayChangeOf(
state: BuilderProgramState,
path: Path,
cancellationToken: CancellationToken | undefined,
computeHash: BuilderState.ComputeHash,
getCanonicalFileName: GetCanonicalFileName,
host: BuilderProgramHost
): void {
removeSemanticDiagnosticsOf(state, path);
@@ -642,8 +632,7 @@ function handleDtsMayChangeOf(
program,
sourceFile,
cancellationToken,
computeHash,
getCanonicalFileName,
host,
!host.disableUseFileVersionAsSignature
);
// If not dts emit, nothing more to do
@@ -677,8 +666,6 @@ function handleDtsMayChangeOfGlobalScope(
state: BuilderProgramState,
filePath: Path,
cancellationToken: CancellationToken | undefined,
computeHash: BuilderState.ComputeHash,
getCanonicalFileName: GetCanonicalFileName,
host: BuilderProgramHost,
): boolean {
if (!state.fileInfos.get(filePath)?.affectsGlobalScope) return false;
@@ -688,8 +675,6 @@ function handleDtsMayChangeOfGlobalScope(
state,
file.resolvedPath,
cancellationToken,
computeHash,
getCanonicalFileName,
host,
));
removeDiagnosticsOfLibraryFiles(state);
@@ -703,8 +688,6 @@ function handleDtsMayChangeOfReferencingExportOfAffectedFile(
state: BuilderProgramState,
affectedFile: SourceFile,
cancellationToken: CancellationToken | undefined,
computeHash: BuilderState.ComputeHash,
getCanonicalFileName: GetCanonicalFileName,
host: BuilderProgramHost
) {
// If there was change in signature (dts output) for the changed file,
@@ -722,8 +705,8 @@ function handleDtsMayChangeOfReferencingExportOfAffectedFile(
const currentPath = queue.pop()!;
if (!seenFileNamesMap.has(currentPath)) {
seenFileNamesMap.set(currentPath, true);
if (handleDtsMayChangeOfGlobalScope(state, currentPath, cancellationToken, computeHash, getCanonicalFileName, host)) return;
handleDtsMayChangeOf(state, currentPath, cancellationToken, computeHash, getCanonicalFileName, host);
if (handleDtsMayChangeOfGlobalScope(state, currentPath, cancellationToken, host)) return;
handleDtsMayChangeOf(state, currentPath, cancellationToken, host);
if (isChangedSignature(state, currentPath)) {
const currentSourceFile = Debug.checkDefined(state.program).getSourceFileByPath(currentPath)!;
queue.push(...BuilderState.getReferencedByPaths(state, currentSourceFile.resolvedPath));
@@ -736,7 +719,7 @@ function handleDtsMayChangeOfReferencingExportOfAffectedFile(
// Go through exported modules from cache first
// If exported modules has path, all files referencing file exported from are affected
state.exportedModulesMap.getKeys(affectedFile.resolvedPath)?.forEach(exportedFromPath => {
if (handleDtsMayChangeOfGlobalScope(state, exportedFromPath, cancellationToken, computeHash, getCanonicalFileName, host)) return true;
if (handleDtsMayChangeOfGlobalScope(state, exportedFromPath, cancellationToken, host)) return true;
const references = state.referencedMap!.getKeys(exportedFromPath);
return references && forEachKey(references, filePath =>
handleDtsMayChangeOfFileAndExportsOfFile(
@@ -744,8 +727,6 @@ function handleDtsMayChangeOfReferencingExportOfAffectedFile(
filePath,
seenFileAndExportsOfFile,
cancellationToken,
computeHash,
getCanonicalFileName,
host,
)
);
@@ -761,14 +742,12 @@ function handleDtsMayChangeOfFileAndExportsOfFile(
filePath: Path,
seenFileAndExportsOfFile: Set<string>,
cancellationToken: CancellationToken | undefined,
computeHash: BuilderState.ComputeHash,
getCanonicalFileName: GetCanonicalFileName,
host: BuilderProgramHost,
): boolean | undefined {
if (!tryAddToSet(seenFileAndExportsOfFile, filePath)) return undefined;
if (handleDtsMayChangeOfGlobalScope(state, filePath, cancellationToken, computeHash, getCanonicalFileName, host)) return true;
handleDtsMayChangeOf(state, filePath, cancellationToken, computeHash, getCanonicalFileName, host);
if (handleDtsMayChangeOfGlobalScope(state, filePath, cancellationToken, host)) return true;
handleDtsMayChangeOf(state, filePath, cancellationToken, host);
// If exported modules has path, all files referencing file exported from are affected
state.exportedModulesMap!.getKeys(filePath)?.forEach(exportedFromPath =>
@@ -777,8 +756,6 @@ function handleDtsMayChangeOfFileAndExportsOfFile(
exportedFromPath,
seenFileAndExportsOfFile,
cancellationToken,
computeHash,
getCanonicalFileName,
host,
)
);
@@ -790,8 +767,6 @@ function handleDtsMayChangeOfFileAndExportsOfFile(
state,
referencingFilePath,
cancellationToken,
computeHash,
getCanonicalFileName,
host,
)
);
@@ -919,8 +894,9 @@ export function isProgramBundleEmitBuildInfo(info: ProgramBuildInfo): info is Pr
/**
* Gets the program information to be emitted in buildInfo so that we can use it to create new program
*/
function getBuildInfo(state: BuilderProgramState, getCanonicalFileName: GetCanonicalFileName, bundle: BundleBuildInfo | undefined): BuildInfo {
function getBuildInfo(state: BuilderProgramState, bundle: BundleBuildInfo | undefined): BuildInfo {
const currentDirectory = Debug.checkDefined(state.program).getCurrentDirectory();
const getCanonicalFileName = createGetCanonicalFileName(state.program!.useCaseSensitiveFileNames());
const buildInfoDirectory = getDirectoryPath(getNormalizedAbsolutePath(getTsBuildInfoEmitOutputFilePath(state.compilerOptions)!, currentDirectory));
// Convert the file name to Path here if we set the fileName instead to optimize multiple d.ts file emits and having to compute Canonical path
const latestChangedDtsFile = state.latestChangedDtsFile ? relativeToBuildInfoEnsuringAbsolutePath(state.latestChangedDtsFile) : undefined;
@@ -1214,12 +1190,13 @@ function getTextHandlingSourceMapForSignature(text: string, data: WriteFileCallb
/** @internal */
export function computeSignatureWithDiagnostics(
program: Program,
sourceFile: SourceFile,
text: string,
computeHash: BuilderState.ComputeHash | undefined,
getCanonicalFileName: GetCanonicalFileName,
host: HostForComputeHash,
data: WriteFileCallbackData | undefined
) {
let getCanonicalFileName: GetCanonicalFileName | undefined;
text = getTextHandlingSourceMapForSignature(text, data);
let sourceFileDirectory: string | undefined;
if (data?.diagnostics?.length) {
@@ -1227,7 +1204,7 @@ export function computeSignatureWithDiagnostics(
`${locationInfo(diagnostic)}${DiagnosticCategory[diagnostic.category]}${diagnostic.code}: ${flattenDiagnosticMessageText(diagnostic.messageText)}`
).join("\n");
}
return (computeHash ?? generateDjb2Hash)(text);
return (host.createHash ?? generateDjb2Hash)(text);
function flattenDiagnosticMessageText(diagnostic: string | DiagnosticMessageChain | undefined): string {
return isString(diagnostic) ?
@@ -1242,13 +1219,17 @@ export function computeSignatureWithDiagnostics(
function locationInfo(diagnostic: DiagnosticWithLocation) {
if (diagnostic.file.resolvedPath === sourceFile.resolvedPath) return `(${diagnostic.start},${diagnostic.length})`;
if (sourceFileDirectory === undefined) sourceFileDirectory = getDirectoryPath(sourceFile.resolvedPath);
return `${ensurePathIsNonModuleName(getRelativePathFromDirectory(sourceFileDirectory, diagnostic.file.resolvedPath, getCanonicalFileName))}(${diagnostic.start},${diagnostic.length})`;
return `${ensurePathIsNonModuleName(getRelativePathFromDirectory(
sourceFileDirectory,
diagnostic.file.resolvedPath,
getCanonicalFileName ??= createGetCanonicalFileName(program.useCaseSensitiveFileNames())
))}(${diagnostic.start},${diagnostic.length})`;
}
}
/** @internal */
export function computeSignature(text: string, computeHash: BuilderState.ComputeHash | undefined, data?: WriteFileCallbackData) {
return (computeHash ?? generateDjb2Hash)(getTextHandlingSourceMapForSignature(text, data));
export function computeSignature(text: string, host: HostForComputeHash, data?: WriteFileCallbackData) {
return (host.createHash ?? generateDjb2Hash)(getTextHandlingSourceMapForSignature(text, data));
}
/** @internal */
@@ -1265,16 +1246,8 @@ export function createBuilderProgram(kind: BuilderProgramKind, { newProgram, hos
return oldProgram;
}
/**
* Create the canonical file name for identity
*/
const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames());
/**
* Computing hash to for signature verification
*/
const computeHash = maybeBind(host, host.createHash);
const state = createBuilderProgramState(newProgram, getCanonicalFileName, oldState, host.disableUseFileVersionAsSignature);
newProgram.getBuildInfo = bundle => getBuildInfo(state, getCanonicalFileName, bundle);
const state = createBuilderProgramState(newProgram, oldState, host.disableUseFileVersionAsSignature);
newProgram.getBuildInfo = bundle => getBuildInfo(state, bundle);
// To ensure that we arent storing any references to old program or new program without state
newProgram = undefined!; // TODO: GH#18217
@@ -1321,7 +1294,7 @@ export function createBuilderProgram(kind: BuilderProgramKind, { newProgram, hos
* in that order would be used to write the files
*/
function emitNextAffectedFile(writeFile?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): AffectedFileResult<EmitResult> {
let affected = getNextAffectedFile(state, cancellationToken, computeHash, getCanonicalFileName, host);
let affected = getNextAffectedFile(state, cancellationToken, host);
const programEmitKind = getBuilderFileEmit(state.compilerOptions);
let emitKind: BuilderFileEmit = emitOnlyDtsFiles ?
programEmitKind & BuilderFileEmit.AllDts : programEmitKind;
@@ -1402,10 +1375,10 @@ export function createBuilderProgram(kind: BuilderProgramKind, { newProgram, hos
const info = state.fileInfos.get(file.resolvedPath)!;
if (info.signature === file.version) {
const signature = computeSignatureWithDiagnostics(
state.program!,
file,
text,
computeHash,
getCanonicalFileName,
host,
data,
);
// With d.ts diagnostics they are also part of the signature so emitSignature will be different from it since its just hash of d.ts
@@ -1454,7 +1427,7 @@ export function createBuilderProgram(kind: BuilderProgramKind, { newProgram, hos
*/
function handleNewSignature(oldSignatureFormat: EmitSignature | undefined, newSignature: string | undefined) {
const oldSignature = !oldSignatureFormat || isString(oldSignatureFormat) ? oldSignatureFormat : oldSignatureFormat[0];
newSignature ??= computeSignature(text, computeHash, data);
newSignature ??= computeSignature(text, host, data);
// Dont write dts files if they didn't change
if (newSignature === oldSignature) {
// If the signature was encoded as string the dts map options match so nothing to do
@@ -1534,7 +1507,7 @@ export function createBuilderProgram(kind: BuilderProgramKind, { newProgram, hos
*/
function getSemanticDiagnosticsOfNextAffectedFile(cancellationToken?: CancellationToken, ignoreSourceFile?: (sourceFile: SourceFile) => boolean): AffectedFileResult<readonly Diagnostic[]> {
while (true) {
const affected = getNextAffectedFile(state, cancellationToken, computeHash, getCanonicalFileName, host);
const affected = getNextAffectedFile(state, cancellationToken, host);
let result;
if (!affected) return undefined; // Done
else if (affected !== state.program) {

View File

@@ -8,10 +8,6 @@ import {
export type AffectedFileResult<T> = { result: T; affected: SourceFile | Program; } | undefined;
export interface BuilderProgramHost {
/**
* return true if file names are treated with case sensitivity
*/
useCaseSensitiveFileNames(): boolean;
/**
* If provided this would be used this hash instead of actual file shape text for detecting changes
*/
@@ -33,14 +29,11 @@ export interface BuilderProgramHost {
* @internal
*/
storeFilesChangingSignatureDuringEmit?: boolean;
/**
* Gets the current time
*
* @internal
*/
now?(): Date;
}
/** @internal */
export type HostForComputeHash = Pick<BuilderProgramHost, "createHash">;
/**
* Builder to manage the program state changes
*/

View File

@@ -1,6 +1,7 @@
import {
arrayFrom, CancellationToken, computeSignatureWithDiagnostics, CustomTransformers, Debug, EmitOutput, emptyArray,
arrayFrom, CancellationToken, computeSignatureWithDiagnostics, createGetCanonicalFileName, CustomTransformers, Debug, EmitOutput, emptyArray,
ExportedModulesFromDeclarationEmit, GetCanonicalFileName, getDirectoryPath, getSourceFileOfNode,
HostForComputeHash,
isDeclarationFileName, isExternalOrCommonJsModule, isGlobalScopeAugmentation, isJsonSourceFile,
isModuleWithStringLiteralName, isStringLiteral, mapDefined, mapDefinedIterator, ModuleDeclaration,
ModuleKind, outFile, OutputFile, Path, Program, ResolutionMode, some, SourceFile, StringLiteralLike, Symbol,
@@ -158,11 +159,6 @@ export namespace BuilderState {
return false;
}
/**
* Compute the hash to store the shape of the file
*/
export type ComputeHash = ((data: string) => string) | undefined;
function getReferencedFilesFromImportedModuleSymbol(symbol: Symbol): Path[] {
return mapDefined(symbol.declarations, declaration => getSourceFileOfNode(declaration)?.resolvedPath);
}
@@ -272,7 +268,7 @@ export namespace BuilderState {
/**
* Creates the state of file references and signature for the new program from oldState if it is safe
*/
export function create(newProgram: Program, getCanonicalFileName: GetCanonicalFileName, oldState?: Readonly<BuilderState>, disableUseFileVersionAsSignature?: boolean): BuilderState {
export function create(newProgram: Program, oldState?: Readonly<BuilderState>, disableUseFileVersionAsSignature?: boolean): BuilderState {
const fileInfos = new Map<Path, FileInfo>();
const options = newProgram.getCompilerOptions();
const isOutFile = outFile(options);
@@ -280,6 +276,7 @@ export namespace BuilderState {
createManyToManyPathMap() : undefined;
const exportedModulesMap = referencedMap ? createManyToManyPathMap() : undefined;
const useOldState = canReuseOldState(referencedMap, oldState);
const getCanonicalFileName = createGetCanonicalFileName(newProgram.useCaseSensitiveFileNames());
// Ensure source files have parent pointers set
newProgram.getTypeChecker();
@@ -340,16 +337,14 @@ export namespace BuilderState {
programOfThisState: Program,
path: Path,
cancellationToken: CancellationToken | undefined,
computeHash: ComputeHash,
getCanonicalFileName: GetCanonicalFileName,
host: HostForComputeHash,
): readonly SourceFile[] {
const result = getFilesAffectedByWithOldState(
state,
programOfThisState,
path,
cancellationToken,
computeHash,
getCanonicalFileName,
host,
);
state.oldSignatures?.clear();
state.oldExportedModulesMap?.clear();
@@ -361,19 +356,18 @@ export namespace BuilderState {
programOfThisState: Program,
path: Path,
cancellationToken: CancellationToken | undefined,
computeHash: ComputeHash,
getCanonicalFileName: GetCanonicalFileName,
host: HostForComputeHash,
): readonly SourceFile[] {
const sourceFile = programOfThisState.getSourceFileByPath(path);
if (!sourceFile) {
return emptyArray;
}
if (!updateShapeSignature(state, programOfThisState, sourceFile, cancellationToken, computeHash, getCanonicalFileName)) {
if (!updateShapeSignature(state, programOfThisState, sourceFile, cancellationToken, host)) {
return [sourceFile];
}
return (state.referencedMap ? getFilesAffectedByUpdatedShapeWhenModuleEmit : getFilesAffectedByUpdatedShapeWhenNonModuleEmit)(state, programOfThisState, sourceFile, cancellationToken, computeHash, getCanonicalFileName);
return (state.referencedMap ? getFilesAffectedByUpdatedShapeWhenModuleEmit : getFilesAffectedByUpdatedShapeWhenNonModuleEmit)(state, programOfThisState, sourceFile, cancellationToken, host);
}
export function updateSignatureOfFile(state: BuilderState, signature: string | undefined, path: Path) {
@@ -389,9 +383,8 @@ export namespace BuilderState {
programOfThisState: Program,
sourceFile: SourceFile,
cancellationToken: CancellationToken | undefined,
computeHash: ComputeHash,
getCanonicalFileName: GetCanonicalFileName,
useFileVersionAsSignature = state.useFileVersionAsSignature
host: HostForComputeHash,
useFileVersionAsSignature = state.useFileVersionAsSignature,
) {
// If we have cached the result for this file, that means hence forth we should assume file shape is uptodate
if (state.hasCalledUpdateShapeSignature?.has(sourceFile.resolvedPath)) return false;
@@ -405,10 +398,10 @@ export namespace BuilderState {
(fileName, text, _writeByteOrderMark, _onError, sourceFiles, data) => {
Debug.assert(isDeclarationFileName(fileName), `File extension for signature expected to be dts: Got:: ${fileName}`);
latestSignature = computeSignatureWithDiagnostics(
programOfThisState,
sourceFile,
text,
computeHash,
getCanonicalFileName,
host,
data,
);
if (latestSignature !== prevSignature) {
@@ -604,8 +597,7 @@ export namespace BuilderState {
programOfThisState: Program,
sourceFileWithUpdatedShape: SourceFile,
cancellationToken: CancellationToken | undefined,
computeHash: ComputeHash,
getCanonicalFileName: GetCanonicalFileName,
host: HostForComputeHash,
) {
if (isFileAffectingGlobalScope(sourceFileWithUpdatedShape)) {
return getAllFilesExcludingDefaultLibraryFile(state, programOfThisState, sourceFileWithUpdatedShape);
@@ -629,7 +621,7 @@ export namespace BuilderState {
if (!seenFileNamesMap.has(currentPath)) {
const currentSourceFile = programOfThisState.getSourceFileByPath(currentPath)!;
seenFileNamesMap.set(currentPath, currentSourceFile);
if (currentSourceFile && updateShapeSignature(state, programOfThisState, currentSourceFile, cancellationToken, computeHash, getCanonicalFileName)) {
if (currentSourceFile && updateShapeSignature(state, programOfThisState, currentSourceFile, cancellationToken, host)) {
queue.push(...getReferencedByPaths(state, currentSourceFile.resolvedPath));
}
}

View File

@@ -637,7 +637,7 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
if (sourceMapFilePath) {
const sourceMap = sourceMapGenerator.toString();
writeFile(host, emitterDiagnostics, sourceMapFilePath, sourceMap, /*writeByteOrderMark*/ false, sourceFiles);
if (printer.bundleFileInfo) printer.bundleFileInfo.mapHash = computeSignature(sourceMap, maybeBind(host, host.createHash));
if (printer.bundleFileInfo) printer.bundleFileInfo.mapHash = computeSignature(sourceMap, host);
}
}
else {
@@ -649,7 +649,7 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
writeFile(host, emitterDiagnostics, jsFilePath, text, !!compilerOptions.emitBOM, sourceFiles, { sourceMapUrlPos, diagnostics: transform.diagnostics });
// We store the hash of the text written in the buildinfo to ensure that text of the referenced d.ts file is same as whats in the buildinfo
// This is needed because incremental can be toggled between two runs and we might use stale file text to do text manipulation in prepend mode
if (printer.bundleFileInfo) printer.bundleFileInfo.hash = computeSignature(text, maybeBind(host, host.createHash));
if (printer.bundleFileInfo) printer.bundleFileInfo.hash = computeSignature(text, host);
// Reset state
writer.clear();
@@ -846,7 +846,6 @@ function emitUsingBuildInfoWorker(
getCommandLine: (ref: ProjectReference) => ParsedCommandLine | undefined,
customTransformers?: CustomTransformers
): EmitUsingBuildInfoResult {
const createHash = maybeBind(host, host.createHash);
const { buildInfoPath, jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath } = getOutputPathsForBundle(config.options, /*forceDtsPaths*/ false);
// If host directly provides buildinfo we can get it directly. This allows host to cache the buildinfo
const buildInfo = host.getBuildInfo!(buildInfoPath!, config.options.configFilePath);
@@ -856,20 +855,20 @@ function emitUsingBuildInfoWorker(
const jsFileText = host.readFile(Debug.checkDefined(jsFilePath));
if (!jsFileText) return jsFilePath!;
// If the jsFileText is not same has what it was created with, tsbuildinfo is stale so dont use it
if (computeSignature(jsFileText, createHash) !== buildInfo.bundle.js.hash) return jsFilePath!;
if (computeSignature(jsFileText, host) !== buildInfo.bundle.js.hash) 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";
if (sourceMapFilePath && computeSignature(sourceMapText!, createHash) !== buildInfo.bundle.js.mapHash) return sourceMapFilePath;
if (sourceMapFilePath && computeSignature(sourceMapText!, host) !== buildInfo.bundle.js.mapHash) return sourceMapFilePath;
// read declaration text
const declarationText = declarationFilePath && host.readFile(declarationFilePath);
if (declarationFilePath && !declarationText) return declarationFilePath;
if (declarationFilePath && computeSignature(declarationText!, createHash) !== buildInfo.bundle.dts!.hash) return declarationFilePath;
if (declarationFilePath && computeSignature(declarationText!, host) !== buildInfo.bundle.dts!.hash) return declarationFilePath;
const declarationMapText = declarationMapPath && host.readFile(declarationMapPath);
// error if no source map or for now if inline sourcemap
if ((declarationMapPath && !declarationMapText) || config.options.inlineSourceMap) return declarationMapPath || "inline sourcemap decoding";
if (declarationMapPath && computeSignature(declarationMapText!, createHash) !== buildInfo.bundle.dts!.mapHash) return declarationMapPath;
if (declarationMapPath && computeSignature(declarationMapText!, host) !== buildInfo.bundle.dts!.mapHash) return declarationMapPath;
const buildInfoDirectory = getDirectoryPath(getNormalizedAbsolutePath(buildInfoPath!, host.getCurrentDirectory()));
const ownPrependInput = createInputFilesWithFileTexts(
@@ -936,7 +935,7 @@ function emitUsingBuildInfoWorker(
const program = buildInfo.program;
if (program && changedDtsText !== undefined && config.options.composite) {
// Update the output signature
(program as ProgramBundleEmitBuildInfo).outSignature = computeSignature(changedDtsText, createHash, changedDtsData);
(program as ProgramBundleEmitBuildInfo).outSignature = computeSignature(changedDtsText, host, changedDtsData);
}
// Update sourceFileInfo
const { js, dts, sourceFiles } = buildInfo.bundle!;
@@ -950,7 +949,7 @@ function emitUsingBuildInfoWorker(
getSourceFileFromReference: returnUndefined,
redirectTargetsMap: createMultiMap(),
getFileIncludeReasons: notImplemented,
createHash,
createHash: maybeBind(host, host.createHash),
};
emitFiles(
notImplementedResolver,

View File

@@ -332,6 +332,8 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
autoImportProviderHost: AutoImportProviderProject | false | undefined;
/** @internal */
protected typeAcquisition: TypeAcquisition | undefined;
/** @internal */
createHash = maybeBind(this.projectService.host, this.projectService.host.createHash);
/** @internal */
constructor(
@@ -740,15 +742,14 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
return [];
}
updateProjectIfDirty(this);
this.builderState = BuilderState.create(this.program!, this.projectService.toCanonicalFileName, this.builderState, /*disableUseFileVersionAsSignature*/ true);
this.builderState = BuilderState.create(this.program!, this.builderState, /*disableUseFileVersionAsSignature*/ true);
return mapDefined(
BuilderState.getFilesAffectedBy(
this.builderState,
this.program!,
scriptInfo.path,
this.cancellationToken,
maybeBind(this.projectService.host, this.projectService.host.createHash),
this.getCanonicalFileName,
this.projectService.host,
),
sourceFile => this.shouldEmitFile(this.projectService.getScriptInfoForPath(sourceFile.path)) ? sourceFile.fileName : undefined
);

View File

@@ -1398,6 +1398,7 @@ export function createLanguageService(
trace: maybeBind(host, host.trace),
resolveModuleNames: maybeBind(host, host.resolveModuleNames),
getModuleResolutionCache: maybeBind(host, host.getModuleResolutionCache),
createHash: maybeBind(host, host.createHash),
resolveTypeReferenceDirectives: maybeBind(host, host.resolveTypeReferenceDirectives),
useSourceOfProjectReferenceRedirect: maybeBind(host, host.useSourceOfProjectReferenceRedirect),
getParsedCommandLine,

View File

@@ -303,6 +303,7 @@ export interface LanguageServiceHost extends GetEffectiveTypeRootsHost, MinimalR
*/
readDirectory?(path: string, extensions?: readonly string[], exclude?: readonly string[], include?: readonly string[], depth?: number): string[];
realpath?(path: string): string;
/** @internal */ createHash?(data: string): string;
/*
* Unlike `realpath and `readDirectory`, `readFile` and `fileExists` are now _required_

View File

@@ -74,7 +74,7 @@ describe("unittests:: builder", () => {
});
function makeAssertChanges(getProgram: () => ts.Program): (fileNames: readonly string[]) => void {
const host: ts.BuilderProgramHost = { useCaseSensitiveFileNames: ts.returnTrue };
const host: ts.BuilderProgramHost = { };
let builderProgram: ts.EmitAndSemanticDiagnosticsBuilderProgram | undefined;
return fileNames => {
const program = getProgram();
@@ -88,7 +88,7 @@ function makeAssertChanges(getProgram: () => ts.Program): (fileNames: readonly s
}
function makeAssertChangesWithCancellationToken(getProgram: () => ts.Program): (fileNames: readonly string[], cancelAfterEmitLength?: number) => void {
const host: ts.BuilderProgramHost = { useCaseSensitiveFileNames: ts.returnTrue };
const host: ts.BuilderProgramHost = { };
let builderProgram: ts.EmitAndSemanticDiagnosticsBuilderProgram | undefined;
let cancel = false;
const cancellationToken: ts.CancellationToken = {

View File

@@ -9431,10 +9431,6 @@ declare namespace ts {
affected: SourceFile | Program;
} | undefined;
interface BuilderProgramHost {
/**
* return true if file names are treated with case sensitivity
*/
useCaseSensitiveFileNames(): boolean;
/**
* If provided this would be used this hash instead of actual file shape text for detecting changes
*/

View File

@@ -5495,10 +5495,6 @@ declare namespace ts {
affected: SourceFile | Program;
} | undefined;
interface BuilderProgramHost {
/**
* return true if file names are treated with case sensitivity
*/
useCaseSensitiveFileNames(): boolean;
/**
* If provided this would be used this hash instead of actual file shape text for detecting changes
*/