mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Handle root files listed in project config from referenced project to be same as if they were included through import (#58560)
This commit is contained in:
+43
-9
@@ -1,6 +1,7 @@
|
||||
import {
|
||||
addRange,
|
||||
AffectedFileResult,
|
||||
append,
|
||||
arrayFrom,
|
||||
arrayToMap,
|
||||
BuilderProgram,
|
||||
@@ -990,10 +991,13 @@ export type ProgramBuildInfoRootStartEnd = [start: ProgramBuildInfoFileId, end:
|
||||
*/
|
||||
export type ProgramBuildInfoRoot = ProgramBuildInfoRootStartEnd | ProgramBuildInfoFileId;
|
||||
/** @internal */
|
||||
export type ProgramBuildInfoResolvedRoot = [resolved: ProgramBuildInfoFileId, root: ProgramBuildInfoFileId];
|
||||
/** @internal */
|
||||
export interface ProgramMultiFileEmitBuildInfo {
|
||||
fileNames: readonly string[];
|
||||
fileInfos: readonly ProgramMultiFileEmitBuildInfoFileInfo[];
|
||||
root: readonly ProgramBuildInfoRoot[];
|
||||
resolvedRoot: readonly ProgramBuildInfoResolvedRoot[] | undefined;
|
||||
options: CompilerOptions | undefined;
|
||||
fileIdsList: readonly (readonly ProgramBuildInfoFileId[])[] | undefined;
|
||||
referencedMap: ProgramBuildInfoReferencedMap | undefined;
|
||||
@@ -1023,6 +1027,7 @@ export interface ProgramBundleEmitBuildInfo {
|
||||
fileNames: readonly string[];
|
||||
fileInfos: readonly ProgramBundleEmitBuildInfoFileInfo[];
|
||||
root: readonly ProgramBuildInfoRoot[];
|
||||
resolvedRoot: readonly ProgramBuildInfoResolvedRoot[] | undefined;
|
||||
options: CompilerOptions | undefined;
|
||||
outSignature: EmitSignature | undefined;
|
||||
latestChangedDtsFile: string | undefined;
|
||||
@@ -1047,6 +1052,7 @@ function getBuildInfo(state: BuilderProgramState): BuildInfo {
|
||||
const latestChangedDtsFile = state.latestChangedDtsFile ? relativeToBuildInfoEnsuringAbsolutePath(state.latestChangedDtsFile) : undefined;
|
||||
const fileNames: string[] = [];
|
||||
const fileNameToFileId = new Map<string, ProgramBuildInfoFileId>();
|
||||
const rootFileNames = new Set(state.program!.getRootFileNames().map(f => toPath(f, currentDirectory, state.program!.getCanonicalFileName)));
|
||||
const root: ProgramBuildInfoRoot[] = [];
|
||||
if (state.compilerOptions.outFile) {
|
||||
// Copy all fileInfo, version and impliedFormat
|
||||
@@ -1063,6 +1069,7 @@ function getBuildInfo(state: BuilderProgramState): BuildInfo {
|
||||
fileNames,
|
||||
fileInfos,
|
||||
root,
|
||||
resolvedRoot: toResolvedRoot(),
|
||||
options: convertToProgramBuildInfoCompilerOptions(state.compilerOptions),
|
||||
outSignature: state.outSignature,
|
||||
latestChangedDtsFile,
|
||||
@@ -1090,7 +1097,8 @@ function getBuildInfo(state: BuilderProgramState): BuildInfo {
|
||||
if (!isJsonSourceFile(file) && sourceFileMayBeEmitted(file, state.program!)) {
|
||||
const emitSignature = state.emitSignatures?.get(key);
|
||||
if (emitSignature !== actualSignature) {
|
||||
(emitSignatures ||= []).push(
|
||||
emitSignatures = append(
|
||||
emitSignatures,
|
||||
emitSignature === undefined ?
|
||||
fileId : // There is no emit, encode as false
|
||||
// fileId, signature: emptyArray if signature only differs in dtsMap option than our own compilerOptions otherwise EmitSignature
|
||||
@@ -1133,7 +1141,8 @@ function getBuildInfo(state: BuilderProgramState): BuildInfo {
|
||||
const file = state.program!.getSourceFileByPath(path);
|
||||
if (!file || !sourceFileMayBeEmitted(file, state.program!)) continue;
|
||||
const fileId = toFileId(path), pendingEmit = state.affectedFilesPendingEmit.get(path)!;
|
||||
(affectedFilesPendingEmit ||= []).push(
|
||||
affectedFilesPendingEmit = append(
|
||||
affectedFilesPendingEmit,
|
||||
pendingEmit === fullEmitForOptions ?
|
||||
fileId : // Pending full emit per options
|
||||
pendingEmit === BuilderFileEmit.Dts ?
|
||||
@@ -1147,7 +1156,7 @@ function getBuildInfo(state: BuilderProgramState): BuildInfo {
|
||||
let changeFileSet: ProgramBuildInfoFileId[] | undefined;
|
||||
if (state.changedFilesSet.size) {
|
||||
for (const path of arrayFrom(state.changedFilesSet.keys()).sort(compareStringsCaseSensitive)) {
|
||||
(changeFileSet ||= []).push(toFileId(path));
|
||||
changeFileSet = append(changeFileSet, toFileId(path));
|
||||
}
|
||||
}
|
||||
const emitDiagnosticsPerFile = convertToProgramBuildInfoDiagnostics(state.emitDiagnosticsPerFile);
|
||||
@@ -1155,6 +1164,7 @@ function getBuildInfo(state: BuilderProgramState): BuildInfo {
|
||||
fileNames,
|
||||
fileInfos,
|
||||
root,
|
||||
resolvedRoot: toResolvedRoot(),
|
||||
options: convertToProgramBuildInfoCompilerOptions(state.compilerOptions),
|
||||
fileIdsList,
|
||||
referencedMap,
|
||||
@@ -1189,8 +1199,8 @@ function getBuildInfo(state: BuilderProgramState): BuildInfo {
|
||||
const key = fileIds.join();
|
||||
let fileIdListId = fileNamesToFileIdListId?.get(key);
|
||||
if (fileIdListId === undefined) {
|
||||
(fileIdsList ||= []).push(fileIds);
|
||||
(fileNamesToFileIdListId ||= new Map()).set(key, fileIdListId = fileIdsList.length as ProgramBuildInfoFileIdListId);
|
||||
fileIdsList = append(fileIdsList, fileIds);
|
||||
(fileNamesToFileIdListId ??= new Map()).set(key, fileIdListId = fileIdsList.length as ProgramBuildInfoFileIdListId);
|
||||
}
|
||||
return fileIdListId;
|
||||
}
|
||||
@@ -1214,6 +1224,17 @@ function getBuildInfo(state: BuilderProgramState): BuildInfo {
|
||||
return root.length = root.length - 1;
|
||||
}
|
||||
|
||||
function toResolvedRoot(): ProgramBuildInfoResolvedRoot[] | undefined {
|
||||
let result: ProgramBuildInfoResolvedRoot[] | undefined;
|
||||
rootFileNames.forEach(path => {
|
||||
const file = state.program!.getSourceFileByPath(path);
|
||||
if (file && path !== file.resolvedPath) {
|
||||
result = append(result, [toFileId(file.resolvedPath), toFileId(path)]);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param optionKey key of CommandLineOption to use to determine if the option should be serialized in tsbuildinfo
|
||||
*/
|
||||
@@ -1253,7 +1274,8 @@ function getBuildInfo(state: BuilderProgramState): BuildInfo {
|
||||
if (diagnostics) {
|
||||
for (const key of arrayFrom(diagnostics.keys()).sort(compareStringsCaseSensitive)) {
|
||||
const value = diagnostics.get(key)!;
|
||||
(result ||= []).push(
|
||||
result = append(
|
||||
result,
|
||||
value.length ?
|
||||
[
|
||||
toFileId(key),
|
||||
@@ -1909,7 +1931,9 @@ export function getBuildInfoFileVersionMap(
|
||||
const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames());
|
||||
const fileInfos = new Map<Path, string>();
|
||||
let rootIndex = 0;
|
||||
const roots: Path[] = [];
|
||||
// Root name to resolved
|
||||
const roots = new Map<Path, Path | undefined>();
|
||||
const resolvedRoots = new Map(program.resolvedRoot);
|
||||
program.fileInfos.forEach((fileInfo, index) => {
|
||||
const path = toPath(program.fileNames[index], buildInfoDirectory, getCanonicalFileName);
|
||||
const version = isString(fileInfo) ? fileInfo : fileInfo.version;
|
||||
@@ -1919,17 +1943,27 @@ export function getBuildInfoFileVersionMap(
|
||||
const fileId = (index + 1) as ProgramBuildInfoFileId;
|
||||
if (isArray(current)) {
|
||||
if (current[0] <= fileId && fileId <= current[1]) {
|
||||
roots.push(path);
|
||||
addRoot(fileId, path);
|
||||
if (current[1] === fileId) rootIndex++;
|
||||
}
|
||||
}
|
||||
else if (current === fileId) {
|
||||
roots.push(path);
|
||||
addRoot(fileId, path);
|
||||
rootIndex++;
|
||||
}
|
||||
}
|
||||
});
|
||||
return { fileInfos, roots };
|
||||
|
||||
function addRoot(fileId: ProgramBuildInfoFileId, path: Path) {
|
||||
const root = resolvedRoots.get(fileId);
|
||||
if (root) {
|
||||
roots.set(toPath(program.fileNames[root - 1], buildInfoDirectory, getCanonicalFileName), path);
|
||||
}
|
||||
else {
|
||||
roots.set(path, undefined);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
|
||||
@@ -3765,7 +3765,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
|
||||
}
|
||||
|
||||
let redirectedPath: Path | undefined;
|
||||
if (isReferencedFile(reason) && !useSourceOfProjectReferenceRedirect) {
|
||||
if (!useSourceOfProjectReferenceRedirect) {
|
||||
const redirectProject = getProjectReferenceRedirectProject(fileName);
|
||||
if (redirectProject) {
|
||||
if (redirectProject.commandLine.options.outFile) {
|
||||
|
||||
@@ -48,6 +48,7 @@ import {
|
||||
findIndex,
|
||||
flattenDiagnosticMessageText,
|
||||
forEach,
|
||||
forEachEntry,
|
||||
forEachKey,
|
||||
ForegroundColorEscapeSequences,
|
||||
formatColorAndReset,
|
||||
@@ -1734,6 +1735,7 @@ function getUpToDateStatusWorker<T extends BuilderProgram>(state: SolutionBuilde
|
||||
};
|
||||
}
|
||||
|
||||
const inputPath = buildInfoProgram ? toPath(state, inputFile) : undefined;
|
||||
// If an buildInfo is older than the newest input, we can stop checking
|
||||
if (buildInfoTime && buildInfoTime < inputTime) {
|
||||
let version: string | undefined;
|
||||
@@ -1741,8 +1743,9 @@ function getUpToDateStatusWorker<T extends BuilderProgram>(state: SolutionBuilde
|
||||
if (buildInfoProgram) {
|
||||
// Read files and see if they are same, read is anyways cached
|
||||
if (!buildInfoVersionMap) buildInfoVersionMap = getBuildInfoFileVersionMap(buildInfoProgram, buildInfoPath!, host);
|
||||
version = buildInfoVersionMap.fileInfos.get(toPath(state, inputFile));
|
||||
const text = version ? state.readFileWithCache(inputFile) : undefined;
|
||||
const resolvedInputPath = buildInfoVersionMap.roots.get(inputPath!);
|
||||
version = buildInfoVersionMap.fileInfos.get(resolvedInputPath ?? inputPath!);
|
||||
const text = version ? state.readFileWithCache(resolvedInputPath ?? inputFile) : undefined;
|
||||
currentVersion = text !== undefined ? getSourceFileVersionAsHashFromText(host, text) : undefined;
|
||||
if (version && version === currentVersion) pseudoInputUpToDate = true;
|
||||
}
|
||||
@@ -1761,20 +1764,22 @@ function getUpToDateStatusWorker<T extends BuilderProgram>(state: SolutionBuilde
|
||||
newestInputFileTime = inputTime;
|
||||
}
|
||||
|
||||
if (buildInfoProgram) seenRoots.add(toPath(state, inputFile));
|
||||
if (buildInfoProgram) seenRoots.add(inputPath!);
|
||||
}
|
||||
|
||||
if (buildInfoProgram) {
|
||||
if (!buildInfoVersionMap) buildInfoVersionMap = getBuildInfoFileVersionMap(buildInfoProgram, buildInfoPath!, host);
|
||||
for (const existingRoot of buildInfoVersionMap.roots) {
|
||||
if (!seenRoots.has(existingRoot)) {
|
||||
// File was root file when project was built but its not any more
|
||||
return {
|
||||
type: UpToDateStatusType.OutOfDateRoots,
|
||||
buildInfoFile: buildInfoPath!,
|
||||
inputFile: existingRoot,
|
||||
};
|
||||
}
|
||||
const existingRoot = forEachEntry(
|
||||
buildInfoVersionMap.roots,
|
||||
// File was root file when project was built but its not any more
|
||||
(_resolved, existingRoot) => !seenRoots.has(existingRoot) ? existingRoot : undefined,
|
||||
);
|
||||
if (existingRoot) {
|
||||
return {
|
||||
type: UpToDateStatusType.OutOfDateRoots,
|
||||
buildInfoFile: buildInfoPath!,
|
||||
inputFile: existingRoot,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -110,6 +110,7 @@ export * from "./unittests/tsbuildWatch/programUpdates.js";
|
||||
export * from "./unittests/tsbuildWatch/projectsBuilding.js";
|
||||
export * from "./unittests/tsbuildWatch/publicApi.js";
|
||||
export * from "./unittests/tsbuildWatch/reexport.js";
|
||||
export * from "./unittests/tsbuildWatch/roots.js";
|
||||
export * from "./unittests/tsbuildWatch/watchEnvironment.js";
|
||||
export * from "./unittests/tsc/cancellationToken.js";
|
||||
export * from "./unittests/tsc/composite.js";
|
||||
@@ -197,6 +198,7 @@ export * from "./unittests/tsserver/projectReferenceCompileOnSave.js";
|
||||
export * from "./unittests/tsserver/projectReferenceErrors.js";
|
||||
export * from "./unittests/tsserver/projectReferences.js";
|
||||
export * from "./unittests/tsserver/projectReferencesSourcemap.js";
|
||||
export * from "./unittests/tsserver/projectRootFiles.js";
|
||||
export * from "./unittests/tsserver/projects.js";
|
||||
export * from "./unittests/tsserver/projectsWithReferences.js";
|
||||
export * from "./unittests/tsserver/refactors.js";
|
||||
|
||||
@@ -141,10 +141,16 @@ export type ReadableProgramBuildInfoFileInfo<T> = Omit<ts.BuilderState.FileInfo,
|
||||
export type ReadableProgramBuildInfoRoot =
|
||||
| [original: ts.ProgramBuildInfoFileId, readable: string]
|
||||
| [original: ts.ProgramBuildInfoRootStartEnd, readable: readonly string[]];
|
||||
export type ReadableProgramMultiFileEmitBuildInfo = Omit<ts.ProgramMultiFileEmitBuildInfo, "fileIdsList" | "fileInfos" | "root" | "referencedMap" | "semanticDiagnosticsPerFile" | "emitDiagnosticsPerFile" | "affectedFilesPendingEmit" | "changeFileSet" | "emitSignatures"> & {
|
||||
|
||||
export type ReadableProgramBuildInfoResolvedRoot = [
|
||||
original: ts.ProgramBuildInfoResolvedRoot,
|
||||
readable: [resolved: string, root: string],
|
||||
];
|
||||
export type ReadableProgramMultiFileEmitBuildInfo = Omit<ts.ProgramMultiFileEmitBuildInfo, "fileIdsList" | "fileInfos" | "root" | "resolvedRoot" | "referencedMap" | "semanticDiagnosticsPerFile" | "emitDiagnosticsPerFile" | "affectedFilesPendingEmit" | "changeFileSet" | "emitSignatures"> & {
|
||||
fileNamesList: readonly (readonly string[])[] | undefined;
|
||||
fileInfos: ts.MapLike<ReadableProgramBuildInfoFileInfo<ts.ProgramMultiFileEmitBuildInfoFileInfo>>;
|
||||
root: readonly ReadableProgramBuildInfoRoot[];
|
||||
resolvedRoot: readonly ReadableProgramBuildInfoResolvedRoot[] | undefined;
|
||||
referencedMap: ts.MapLike<string[]> | undefined;
|
||||
semanticDiagnosticsPerFile: readonly ReadableProgramBuildInfoDiagnostic[] | undefined;
|
||||
emitDiagnosticsPerFile: readonly ReadableProgramBuildInfoDiagnostic[] | undefined;
|
||||
@@ -153,9 +159,10 @@ export type ReadableProgramMultiFileEmitBuildInfo = Omit<ts.ProgramMultiFileEmit
|
||||
emitSignatures: readonly ReadableProgramBuildInfoEmitSignature[] | undefined;
|
||||
};
|
||||
export type ReadableProgramBuildInfoBundlePendingEmit = [emitKind: ReadableBuilderFileEmit, original: ts.ProgramBuildInfoBundlePendingEmit];
|
||||
export type ReadableProgramBundleEmitBuildInfo = Omit<ts.ProgramBundleEmitBuildInfo, "fileInfos" | "root" | "pendingEmit"> & {
|
||||
export type ReadableProgramBundleEmitBuildInfo = Omit<ts.ProgramBundleEmitBuildInfo, "fileInfos" | "root" | "resolvedRoot" | "pendingEmit"> & {
|
||||
fileInfos: ts.MapLike<string | ReadableProgramBuildInfoFileInfo<ts.BuilderState.FileInfo>>;
|
||||
root: readonly ReadableProgramBuildInfoRoot[];
|
||||
resolvedRoot: readonly ReadableProgramBuildInfoResolvedRoot[] | undefined;
|
||||
pendingEmit: ReadableProgramBuildInfoBundlePendingEmit | undefined;
|
||||
};
|
||||
|
||||
@@ -180,6 +187,7 @@ function generateBuildInfoProgramBaseline(sys: ts.System, buildInfoPath: string,
|
||||
...buildInfo.program,
|
||||
fileInfos,
|
||||
root: buildInfo.program.root.map(toReadableProgramBuildInfoRoot),
|
||||
resolvedRoot: buildInfo.program.resolvedRoot?.map(toReadableProgramBuildInfoResolvedRoot),
|
||||
pendingEmit: pendingEmit === undefined ?
|
||||
undefined :
|
||||
[
|
||||
@@ -198,6 +206,7 @@ function generateBuildInfoProgramBaseline(sys: ts.System, buildInfoPath: string,
|
||||
fileNamesList,
|
||||
fileInfos: buildInfo.program.fileInfos ? fileInfos : undefined!,
|
||||
root: buildInfo.program.root.map(toReadableProgramBuildInfoRoot),
|
||||
resolvedRoot: buildInfo.program.resolvedRoot?.map(toReadableProgramBuildInfoResolvedRoot),
|
||||
options: buildInfo.program.options,
|
||||
referencedMap: toMapOfReferencedSet(buildInfo.program.referencedMap),
|
||||
semanticDiagnosticsPerFile: toReadableProgramBuildInfoDiagnosticsPerFile(buildInfo.program.semanticDiagnosticsPerFile),
|
||||
@@ -245,6 +254,10 @@ function generateBuildInfoProgramBaseline(sys: ts.System, buildInfoPath: string,
|
||||
return [original, readable];
|
||||
}
|
||||
|
||||
function toReadableProgramBuildInfoResolvedRoot(original: ts.ProgramBuildInfoResolvedRoot): ReadableProgramBuildInfoResolvedRoot {
|
||||
return [original, [toFileName(original[0]), toFileName(original[1])]];
|
||||
}
|
||||
|
||||
function toMapOfReferencedSet(referenceMap: ts.ProgramBuildInfoReferencedMap | undefined): ts.MapLike<string[]> | undefined {
|
||||
if (!referenceMap) return undefined;
|
||||
const result: ts.MapLike<string[]> = {};
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
import { dedent } from "../../_namespaces/Utils.js";
|
||||
import { jsonToReadableText } from "../helpers.js";
|
||||
import {
|
||||
FsContents,
|
||||
libContent,
|
||||
} from "./contents.js";
|
||||
import { libFile } from "./virtualFileSystemWithWatch.js";
|
||||
|
||||
function getFsContentsForRootsFromReferencedProject(serverFirst: boolean): FsContents {
|
||||
return {
|
||||
"/home/src/workspaces/tsconfig.json": jsonToReadableText({
|
||||
compilerOptions: {
|
||||
composite: true,
|
||||
},
|
||||
references: [
|
||||
{ path: "projects/server" },
|
||||
{ path: "projects/shared" },
|
||||
],
|
||||
}),
|
||||
"/home/src/workspaces/projects/shared/src/myClass.ts": `export class MyClass { }`,
|
||||
"/home/src/workspaces/projects/shared/src/logging.ts": dedent`
|
||||
export function log(str: string) {
|
||||
console.log(str);
|
||||
}
|
||||
`,
|
||||
"/home/src/workspaces/projects/shared/src/random.ts": dedent`
|
||||
export function randomFn(str: string) {
|
||||
console.log(str);
|
||||
}
|
||||
`,
|
||||
"/home/src/workspaces/projects/shared/tsconfig.json": jsonToReadableText({
|
||||
extends: "../../tsconfig.json",
|
||||
compilerOptions: {
|
||||
outDir: "./dist",
|
||||
},
|
||||
include: ["src/**/*.ts"],
|
||||
}),
|
||||
"/home/src/workspaces/projects/server/src/server.ts": dedent`
|
||||
import { MyClass } from ':shared/myClass.js';
|
||||
console.log('Hello, world!');
|
||||
`,
|
||||
"/home/src/workspaces/projects/server/tsconfig.json": jsonToReadableText({
|
||||
extends: "../../tsconfig.json",
|
||||
compilerOptions: {
|
||||
baseUrl: "./src",
|
||||
rootDir: "..",
|
||||
outDir: "./dist",
|
||||
paths: {
|
||||
":shared/*": ["../../shared/src/*"],
|
||||
},
|
||||
},
|
||||
include: serverFirst ?
|
||||
["src/**/*.ts", "../shared/src/**/*.ts"] :
|
||||
["../shared/src/**/*.ts", "src/**/*.ts"],
|
||||
references: [
|
||||
{ path: "../shared" },
|
||||
],
|
||||
}),
|
||||
[libFile.path]: libContent,
|
||||
};
|
||||
}
|
||||
|
||||
export function forEachScenarioForRootsFromReferencedProject(action: (subScenario: string, getFsContents: () => FsContents) => void) {
|
||||
action("when root file is from referenced project", () => getFsContentsForRootsFromReferencedProject(/*serverFirst*/ true));
|
||||
action("when root file is from referenced project and shared is first", () => getFsContentsForRootsFromReferencedProject(/*serverFirst*/ false));
|
||||
}
|
||||
@@ -1,7 +1,14 @@
|
||||
import { dedent } from "../../_namespaces/Utils.js";
|
||||
import { jsonToReadableText } from "../helpers.js";
|
||||
import { verifyTsc } from "../helpers/tsc.js";
|
||||
import { loadProjectFromFiles } from "../helpers/vfs.js";
|
||||
import { forEachScenarioForRootsFromReferencedProject } from "../helpers/projectRoots.js";
|
||||
import {
|
||||
noChangeRun,
|
||||
verifyTsc,
|
||||
} from "../helpers/tsc.js";
|
||||
import {
|
||||
appendText,
|
||||
loadProjectFromFiles,
|
||||
} from "../helpers/vfs.js";
|
||||
|
||||
describe("unittests:: tsbuild:: roots::", () => {
|
||||
verifyTsc({
|
||||
@@ -118,4 +125,28 @@ describe("unittests:: tsbuild:: roots::", () => {
|
||||
},
|
||||
}],
|
||||
});
|
||||
|
||||
describe("when root file is from referenced project", () => {
|
||||
forEachScenarioForRootsFromReferencedProject((subScenario, getFsContents) => {
|
||||
verifyTsc({
|
||||
scenario: "roots",
|
||||
subScenario,
|
||||
commandLineArgs: ["--b", "projects/server", "-v", "--traceResolution", "--explainFiles"],
|
||||
fs: () => loadProjectFromFiles(getFsContents(), { cwd: "/home/src/workspaces" }),
|
||||
edits: [
|
||||
noChangeRun,
|
||||
{
|
||||
caption: "edit logging file",
|
||||
edit: fs => appendText(fs, "/home/src/workspaces/projects/shared/src/logging.ts", "export const x = 10;"),
|
||||
},
|
||||
noChangeRun,
|
||||
{
|
||||
caption: "delete random file",
|
||||
edit: fs => fs.unlinkSync("/home/src/workspaces/projects/shared/src/random.ts"),
|
||||
},
|
||||
noChangeRun,
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import { forEachScenarioForRootsFromReferencedProject } from "../helpers/projectRoots.js";
|
||||
import {
|
||||
noopChange,
|
||||
verifyTscWatch,
|
||||
} from "../helpers/tscWatch.js";
|
||||
import { createWatchedSystem } from "../helpers/virtualFileSystemWithWatch.js";
|
||||
|
||||
describe("unittests:: tsbuildWatch:: watchMode:: roots::", () => {
|
||||
describe("when root file is from referenced project", () => {
|
||||
forEachScenarioForRootsFromReferencedProject((subScenario, getFsContents) => {
|
||||
verifyTscWatch({
|
||||
scenario: "roots",
|
||||
subScenario,
|
||||
commandLineArgs: ["--b", "projects/server", "-w", "-v", "--traceResolution", "--explainFiles"],
|
||||
sys: () => createWatchedSystem(getFsContents(), { currentDirectory: "/home/src/workspaces" }),
|
||||
edits: [
|
||||
noopChange,
|
||||
{
|
||||
caption: "edit logging file",
|
||||
edit: sys => sys.appendFile("/home/src/workspaces/projects/shared/src/logging.ts", "export const x = 10;"),
|
||||
timeouts: sys => {
|
||||
sys.runQueuedTimeoutCallbacks(); // build shared
|
||||
sys.runQueuedTimeoutCallbacks(); // build server
|
||||
},
|
||||
},
|
||||
noopChange,
|
||||
{
|
||||
caption: "delete random file",
|
||||
edit: sys => sys.deleteFile("/home/src/workspaces/projects/shared/src/random.ts"),
|
||||
timeouts: sys => {
|
||||
sys.runQueuedTimeoutCallbacks(); // build shared
|
||||
sys.runQueuedTimeoutCallbacks(); // build server
|
||||
},
|
||||
},
|
||||
noopChange,
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,27 @@
|
||||
import { forEachScenarioForRootsFromReferencedProject } from "../helpers/projectRoots.js";
|
||||
import {
|
||||
baselineTsserverLogs,
|
||||
openFilesForSession,
|
||||
TestSession,
|
||||
} from "../helpers/tsserver.js";
|
||||
import { createServerHost } from "../helpers/virtualFileSystemWithWatch.js";
|
||||
|
||||
describe("unittests:: tsserver:: projectRootFiles:: roots::", () => {
|
||||
describe("when root file is from referenced project", () => {
|
||||
forEachScenarioForRootsFromReferencedProject((subScenario, getFsContents) => {
|
||||
it(subScenario, () => {
|
||||
const host = createServerHost(getFsContents(), { currentDirectory: "/home/src/workspaces" });
|
||||
const session = new TestSession(host);
|
||||
openFilesForSession(["/home/src/workspaces/projects/server/src/server.ts"], session);
|
||||
|
||||
host.appendFile("/home/src/workspaces/projects/shared/src/logging.ts", "export const x = 10;");
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
|
||||
host.deleteFile("/home/src/workspaces/projects/shared/src/random.ts");
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
|
||||
baselineTsserverLogs("projectRootFiles", subScenario, session);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user