mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-06 20:14:01 -06:00
Fix the project reference verification to include json source file version check
This commit is contained in:
parent
aac961e60d
commit
b6129b452f
@ -842,7 +842,7 @@ namespace ts {
|
||||
return deduplicateSorted(sort(array, comparer), equalityComparer || comparer);
|
||||
}
|
||||
|
||||
export function arrayIsEqualTo<T>(array1: ReadonlyArray<T> | undefined, array2: ReadonlyArray<T> | undefined, equalityComparer: (a: T, b: T) => boolean = equateValues): boolean {
|
||||
export function arrayIsEqualTo<T>(array1: ReadonlyArray<T> | undefined, array2: ReadonlyArray<T> | undefined, equalityComparer: (a: T, b: T, index: number) => boolean = equateValues): boolean {
|
||||
if (!array1 || !array2) {
|
||||
return array1 === array2;
|
||||
}
|
||||
@ -852,7 +852,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
for (let i = 0; i < array1.length; i++) {
|
||||
if (!equalityComparer(array1[i], array2[i])) {
|
||||
if (!equalityComparer(array1[i], array2[i], i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -455,7 +455,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// If project references dont match
|
||||
if (!arrayIsEqualTo(program.getProjectReferences(), projectReferences)) {
|
||||
if (!arrayIsEqualTo(program.getProjectReferences(), projectReferences, projectReferenceUptoDate)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -483,9 +483,27 @@ namespace ts {
|
||||
|
||||
return true;
|
||||
|
||||
function sourceFileNotUptoDate(sourceFile: SourceFile): boolean {
|
||||
return sourceFile.version !== getSourceVersion(sourceFile.path) ||
|
||||
hasInvalidatedResolution(sourceFile.path);
|
||||
function sourceFileNotUptoDate(sourceFile: SourceFile) {
|
||||
return !sourceFileVersionUptoDate(sourceFile) ||
|
||||
hasInvalidatedResolution(sourceFile.resolvedPath || sourceFile.path);
|
||||
}
|
||||
|
||||
function sourceFileVersionUptoDate(sourceFile: SourceFile) {
|
||||
return sourceFile.version === getSourceVersion(sourceFile.resolvedPath || sourceFile.path);
|
||||
}
|
||||
|
||||
function projectReferenceUptoDate(oldRef: ProjectReference, newRef: ProjectReference, index: number) {
|
||||
if (!projectReferenceIsEqualTo(oldRef, newRef)) {
|
||||
return false;
|
||||
}
|
||||
const oldResolvedRef = program!.getResolvedProjectReferences()![index];
|
||||
if (oldResolvedRef) {
|
||||
// If sourceFile for the oldResolvedRef existed, check the version for uptodate
|
||||
return sourceFileVersionUptoDate(oldResolvedRef.sourceFile);
|
||||
}
|
||||
// In old program, not able to resolve project reference path,
|
||||
// so if config file doesnt exist, it is uptodate.
|
||||
return !fileExists(resolveProjectReferencePath(oldRef));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -187,9 +187,10 @@ interface Array<T> {}`
|
||||
}
|
||||
|
||||
export function checkArray(caption: string, actual: ReadonlyArray<string>, expected: ReadonlyArray<string>) {
|
||||
checkMapKeys(caption, arrayToMap(actual, identity), expected);
|
||||
assert.equal(actual.length, expected.length, `${caption}: incorrect actual number of files, expected:\r\n${expected.join("\r\n")}\r\ngot: ${actual.join("\r\n")}`);
|
||||
for (const f of expected) {
|
||||
assert.equal(true, contains(actual, f), `${caption}: expected to find ${f} in ${actual}`);
|
||||
assert.isTrue(contains(actual, f), `${caption}: expected to find ${f} in ${actual}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -34,6 +34,10 @@ namespace ts.tscWatch {
|
||||
return `${projectPath(subProject)}/${baseFileName.toLowerCase()}`;
|
||||
}
|
||||
|
||||
function projectFileName(subProject: SubProject, baseFileName: string) {
|
||||
return `${projectPath(subProject)}/${baseFileName}`;
|
||||
}
|
||||
|
||||
function projectFile(subProject: SubProject, baseFileName: string): File {
|
||||
return {
|
||||
path: projectFilePath(subProject, baseFileName),
|
||||
@ -391,10 +395,10 @@ let x: string = 10;`);
|
||||
});
|
||||
|
||||
describe("tsc-watch works with project references", () => {
|
||||
const coreIndexDts = projectFilePath(SubProject.core, "index.d.ts");
|
||||
const coreAnotherModuleDts = projectFilePath(SubProject.core, "anotherModule.d.ts");
|
||||
const logicIndexDts = projectFilePath(SubProject.logic, "index.d.ts");
|
||||
const expectedWatchedFiles = [core[0], logic[0], ...tests, libFile].map(f => f.path).concat(coreIndexDts, coreAnotherModuleDts, logicIndexDts);
|
||||
const coreIndexDts = projectFileName(SubProject.core, "index.d.ts");
|
||||
const coreAnotherModuleDts = projectFileName(SubProject.core, "anotherModule.d.ts");
|
||||
const logicIndexDts = projectFileName(SubProject.logic, "index.d.ts");
|
||||
const expectedWatchedFiles = [core[0], logic[0], ...tests, libFile].map(f => f.path).concat([coreIndexDts, coreAnotherModuleDts, logicIndexDts].map(f => f.toLowerCase()));
|
||||
const expectedWatchedDirectoriesRecursive = projectSystem.getTypeRootsFromLocation(projectPath(SubProject.tests));
|
||||
|
||||
function createSolution() {
|
||||
@ -432,7 +436,7 @@ let x: string = 10;`);
|
||||
}
|
||||
|
||||
function verifyDependencies(watch: () => BuilderProgram, filePath: string, expected: ReadonlyArray<string>) {
|
||||
checkArray(`${filePath} dependencies`, watch().getAllDependencies(watch().getSourceFile(filePath)!).map(f => f.toLocaleLowerCase()), expected);
|
||||
checkArray(`${filePath} dependencies`, watch().getAllDependencies(watch().getSourceFile(filePath)!), expected);
|
||||
}
|
||||
|
||||
describe("invoking when references are already built", () => {
|
||||
@ -447,7 +451,7 @@ let x: string = 10;`);
|
||||
});
|
||||
|
||||
it("local edit in ts file, result in watch compilation because logic.d.ts is written", () => {
|
||||
const { host, solutionBuilder } = createSolutionAndWatchMode();
|
||||
const { host, solutionBuilder, watch } = createSolutionAndWatchMode();
|
||||
host.writeFile(logic[1].path, `${logic[1].content}
|
||||
function foo() {
|
||||
}`);
|
||||
@ -456,10 +460,11 @@ function foo() {
|
||||
|
||||
host.checkTimeoutQueueLengthAndRun(1); // not ideal, but currently because of d.ts but no new file is written
|
||||
checkOutputErrorsIncremental(host, emptyArray);
|
||||
checkProgramActualFiles(watch().getProgram(), [tests[1].path, libFile.path, coreIndexDts, coreAnotherModuleDts, logicIndexDts]);
|
||||
});
|
||||
|
||||
it("non local edit in ts file, rebuilds in watch compilation", () => {
|
||||
const { host, solutionBuilder } = createSolutionAndWatchMode();
|
||||
const { host, solutionBuilder, watch } = createSolutionAndWatchMode();
|
||||
host.writeFile(logic[1].path, `${logic[1].content}
|
||||
export function gfoo() {
|
||||
}`);
|
||||
@ -468,8 +473,26 @@ export function gfoo() {
|
||||
|
||||
host.checkTimeoutQueueLengthAndRun(1);
|
||||
checkOutputErrorsIncremental(host, emptyArray);
|
||||
checkProgramActualFiles(watch().getProgram(), [tests[1].path, libFile.path, coreIndexDts, coreAnotherModuleDts, logicIndexDts]);
|
||||
});
|
||||
|
||||
it("change in project reference config file builds correctly", () => {
|
||||
const { host, solutionBuilder, watch } = createSolutionAndWatchMode();
|
||||
host.writeFile(logic[0].path, JSON.stringify({
|
||||
compilerOptions: { composite: true, declaration: true, declarationDir: "decls" },
|
||||
references: [{ path: "../core" }]
|
||||
}));
|
||||
solutionBuilder.invalidateProject(logic[0].path, ConfigFileProgramReloadLevel.Full);
|
||||
solutionBuilder.buildInvalidatedProject();
|
||||
|
||||
host.checkTimeoutQueueLengthAndRun(1);
|
||||
checkOutputErrorsIncremental(host, [
|
||||
// TODO: #26036
|
||||
// The error is reported in d.ts file because it isnt resolved from ts file path, but is resolved from .d.ts file
|
||||
"sample1/logic/decls/index.d.ts(2,22): error TS2307: Cannot find module '../core/anotherModule'.\n"
|
||||
]);
|
||||
checkProgramActualFiles(watch().getProgram(), [tests[1].path, libFile.path, coreIndexDts, coreAnotherModuleDts, projectFilePath(SubProject.logic, "decls/index.d.ts")]);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user