Skip to content

Commit a172751

Browse files
committed
Always resolve the config file to ResolvedConfigFile if its json, otherwise combine tsconfig.json
1 parent ec38ca4 commit a172751

File tree

6 files changed

+28
-71
lines changed

6 files changed

+28
-71
lines changed

src/compiler/program.ts

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2341,7 +2341,7 @@ namespace ts {
23412341

23422342
function parseProjectReferenceConfigFile(ref: ProjectReference): { commandLine: ParsedCommandLine, sourceFile: SourceFile } | undefined {
23432343
// The actual filename (i.e. add "/tsconfig.json" if necessary)
2344-
const refPath = resolveProjectReferencePath(host, ref);
2344+
const refPath = resolveProjectReferencePath(ref);
23452345
// An absolute path pointing to the containing directory of the config file
23462346
const basePath = getNormalizedAbsolutePath(getDirectoryPath(refPath), host.getCurrentDirectory());
23472347
const sourceFile = host.getSourceFile(refPath, ScriptTarget.JSON) as JsonSourceFile | undefined;
@@ -2820,18 +2820,13 @@ namespace ts {
28202820
};
28212821
}
28222822

2823-
export interface ResolveProjectReferencePathHost {
2824-
fileExists(fileName: string): boolean;
2825-
}
28262823
/**
28272824
* Returns the target config filename of a project reference.
28282825
* Note: The file might not exist.
28292826
*/
2830-
export function resolveProjectReferencePath(host: ResolveProjectReferencePathHost, ref: ProjectReference): ResolvedConfigFileName {
2831-
if (!host.fileExists(ref.path)) {
2832-
return combinePaths(ref.path, "tsconfig.json") as ResolvedConfigFileName;
2833-
}
2834-
return ref.path as ResolvedConfigFileName;
2827+
// TODO: Does this need to be exposed
2828+
export function resolveProjectReferencePath(ref: ProjectReference): ResolvedConfigFileName {
2829+
return resolveConfigFileProjectName(ref.path);
28352830
}
28362831

28372832
/* @internal */

src/compiler/tsbuild.ts

Lines changed: 20 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,7 @@ namespace ts {
598598

599599
function invalidateProjectAndScheduleBuilds(resolved: ResolvedConfigFileName, reloadLevel: ConfigFileProgramReloadLevel) {
600600
reportFileChangeDetected = true;
601-
invalidateProject(resolved, reloadLevel);
601+
invalidateResolvedProject(resolved, reloadLevel);
602602
scheduleBuildInvalidatedProject();
603603
}
604604

@@ -716,7 +716,7 @@ namespace ts {
716716
if (project.projectReferences) {
717717
for (const ref of project.projectReferences) {
718718
usesPrepend = usesPrepend || !!(ref.prepend);
719-
const resolvedRef = resolveProjectReferencePath(host, ref);
719+
const resolvedRef = resolveProjectReferencePath(ref);
720720
const refStatus = getUpToDateStatus(parseConfigFile(resolvedRef));
721721

722722
// An upstream project is blocked
@@ -795,16 +795,10 @@ namespace ts {
795795
}
796796

797797
function invalidateProject(configFileName: string, reloadLevel?: ConfigFileProgramReloadLevel) {
798-
const resolved = resolveProjectName(configFileName);
799-
if (resolved === undefined) {
800-
// If this was a rootName, we need to track it as missing.
801-
// Otherwise we can just ignore it and have it possibly surface as an error in any downstream projects,
802-
// if they exist
803-
804-
// TODO: do those things
805-
return;
806-
}
798+
invalidateResolvedProject(resolveProjectName(configFileName), reloadLevel);
799+
}
807800

801+
function invalidateResolvedProject(resolved: ResolvedConfigFileName, reloadLevel?: ConfigFileProgramReloadLevel) {
808802
projectStatus.removeKey(resolved);
809803
if (options.watch) {
810804
diagnostics.removeKey(resolved);
@@ -901,11 +895,9 @@ namespace ts {
901895
}
902896
}
903897

904-
function buildSingleInvalidatedProject(project: ResolvedConfigFileName, reloadLevel: ConfigFileProgramReloadLevel) {
898+
function buildSingleInvalidatedProject(resolved: ResolvedConfigFileName, reloadLevel: ConfigFileProgramReloadLevel) {
905899
// TODO:: handle this in better way later
906900

907-
const resolved = resolveProjectName(project);
908-
if (!resolved) return; // ??
909901
const proj = parseConfigFile(resolved);
910902
if (!proj) return; // ?
911903
if (reloadLevel === ConfigFileProgramReloadLevel.Full) {
@@ -915,7 +907,7 @@ namespace ts {
915907
}
916908
else if (reloadLevel === ConfigFileProgramReloadLevel.Partial) {
917909
// Update file names
918-
const result = getFileNamesFromConfigSpecs(proj.configFileSpecs!, getDirectoryPath(project), proj.options, parseConfigFileHost);
910+
const result = getFileNamesFromConfigSpecs(proj.configFileSpecs!, getDirectoryPath(resolved), proj.options, parseConfigFileHost);
919911
if (result.fileNames.length !== 0) {
920912
filterMutate(proj.errors, error => !isErrorNoInputFiles(error));
921913
}
@@ -927,14 +919,14 @@ namespace ts {
927919
}
928920

929921
const status = getUpToDateStatus(proj);
930-
verboseReportProjectStatus(project, status);
922+
verboseReportProjectStatus(resolved, status);
931923

932924
if (status.type === UpToDateStatusType.UpstreamBlocked) {
933925
if (options.verbose) reportStatus(Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_has_errors, resolved, status.upstreamProjectName);
934926
return;
935927
}
936928

937-
buildSingleProject(project);
929+
buildSingleProject(resolved);
938930
}
939931

940932
function createDependencyGraph(roots: ResolvedConfigFileName[]): DependencyGraph | undefined {
@@ -982,10 +974,6 @@ namespace ts {
982974
if (parsed.projectReferences) {
983975
for (const ref of parsed.projectReferences) {
984976
const resolvedRefPath = resolveProjectName(ref.path);
985-
if (resolvedRefPath === undefined) {
986-
hadError = true;
987-
break;
988-
}
989977
visit(resolvedRefPath, inCircularContext || ref.circular);
990978
graph.addReference(projPath, resolvedRefPath);
991979
}
@@ -1184,30 +1172,12 @@ namespace ts {
11841172
return ExitStatus.Success;
11851173
}
11861174

1187-
function resolveProjectName(name: string): ResolvedConfigFileName | undefined {
1188-
const fullPath = resolvePath(host.getCurrentDirectory(), name);
1189-
if (host.fileExists(fullPath)) {
1190-
return fullPath as ResolvedConfigFileName;
1191-
}
1192-
const fullPathWithTsconfig = combinePaths(fullPath, "tsconfig.json");
1193-
if (host.fileExists(fullPathWithTsconfig)) {
1194-
return fullPathWithTsconfig as ResolvedConfigFileName;
1195-
}
1196-
// TODO(shkamat): right now this is accounted as 1 error in config file, but we need to do better
1197-
host.reportDiagnostic(createCompilerDiagnostic(Diagnostics.File_0_not_found, relName(fullPath)));
1198-
return undefined;
1175+
function resolveProjectName(name: string): ResolvedConfigFileName {
1176+
return resolveConfigFileProjectName(resolvePath(host.getCurrentDirectory(), name));
11991177
}
12001178

12011179
function resolveProjectNames(configFileNames: ReadonlyArray<string>): ResolvedConfigFileName[] | undefined {
1202-
const resolvedNames: ResolvedConfigFileName[] = [];
1203-
for (const name of configFileNames) {
1204-
const resolved = resolveProjectName(name);
1205-
if (resolved === undefined) {
1206-
return undefined;
1207-
}
1208-
resolvedNames.push(resolved);
1209-
}
1210-
return resolvedNames;
1180+
return configFileNames.map(resolveProjectName);
12111181
}
12121182

12131183
function buildAllProjects(): ExitStatus {
@@ -1300,6 +1270,14 @@ namespace ts {
13001270
}
13011271
}
13021272

1273+
export function resolveConfigFileProjectName(project: string): ResolvedConfigFileName {
1274+
if (fileExtensionIs(project, Extension.Json)) {
1275+
return project as ResolvedConfigFileName;
1276+
}
1277+
1278+
return combinePaths(project, "tsconfig.json") as ResolvedConfigFileName;
1279+
}
1280+
13031281
export function getAllProjectOutputs(project: ParsedCommandLine): ReadonlyArray<string> {
13041282
if (project.options.outFile) {
13051283
return getOutFileOutputs(project);

src/testRunner/unittests/tsbuild.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ namespace ts {
199199
tick();
200200
touch(fs, "/src/logic/index.ts");
201201
// Because we haven't reset the build context, the builder should assume there's nothing to do right now
202-
const status = builder.getUpToDateStatusOfFile(builder.resolveProjectName("/src/logic")!);
202+
const status = builder.getUpToDateStatusOfFile(builder.resolveProjectName("/src/logic"));
203203
assert.equal(status.type, UpToDateStatusType.UpToDate, "Project should be assumed to be up-to-date");
204204

205205
// Rebuild this project

src/tsc/tsc.ts

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ namespace ts {
165165
}
166166

167167
function performBuild(args: string[]): number | undefined {
168-
const { buildOptions, projects: buildProjects, errors } = parseBuildCommand(args);
168+
const { buildOptions, projects, errors } = parseBuildCommand(args);
169169
if (errors.length > 0) {
170170
errors.forEach(reportDiagnostic);
171171
return ExitStatus.DiagnosticsPresent_OutputsSkipped;
@@ -179,16 +179,6 @@ namespace ts {
179179

180180
// Update to pretty if host supports it
181181
updateReportDiagnostic();
182-
const projects = mapDefined(buildProjects, project => {
183-
const fileName = resolvePath(sys.getCurrentDirectory(), project);
184-
const refPath = resolveProjectReferencePath(sys, { path: fileName });
185-
if (!sys.fileExists(refPath)) {
186-
reportDiagnostic(createCompilerDiagnostic(Diagnostics.File_0_does_not_exist, fileName));
187-
return undefined;
188-
}
189-
return refPath;
190-
});
191-
192182
if (projects.length === 0) {
193183
printVersion();
194184
printHelp(buildOpts, "--build ");

tests/baselines/reference/api/tsserverlibrary.d.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4182,14 +4182,11 @@ declare namespace ts {
41824182
* @returns A 'Program' object.
41834183
*/
41844184
function createProgram(rootNames: ReadonlyArray<string>, options: CompilerOptions, host?: CompilerHost, oldProgram?: Program, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): Program;
4185-
interface ResolveProjectReferencePathHost {
4186-
fileExists(fileName: string): boolean;
4187-
}
41884185
/**
41894186
* Returns the target config filename of a project reference.
41904187
* Note: The file might not exist.
41914188
*/
4192-
function resolveProjectReferencePath(host: ResolveProjectReferencePathHost, ref: ProjectReference): ResolvedConfigFileName;
4189+
function resolveProjectReferencePath(ref: ProjectReference): ResolvedConfigFileName;
41934190
}
41944191
declare namespace ts {
41954192
interface EmitOutput {

tests/baselines/reference/api/typescript.d.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4182,14 +4182,11 @@ declare namespace ts {
41824182
* @returns A 'Program' object.
41834183
*/
41844184
function createProgram(rootNames: ReadonlyArray<string>, options: CompilerOptions, host?: CompilerHost, oldProgram?: Program, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): Program;
4185-
interface ResolveProjectReferencePathHost {
4186-
fileExists(fileName: string): boolean;
4187-
}
41884185
/**
41894186
* Returns the target config filename of a project reference.
41904187
* Note: The file might not exist.
41914188
*/
4192-
function resolveProjectReferencePath(host: ResolveProjectReferencePathHost, ref: ProjectReference): ResolvedConfigFileName;
4189+
function resolveProjectReferencePath(ref: ProjectReference): ResolvedConfigFileName;
41934190
}
41944191
declare namespace ts {
41954192
interface EmitOutput {

0 commit comments

Comments
 (0)