mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-20 05:06:25 -05:00
Removing some unnecessary methods from host and function parameters (#51499)
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user