Skip to content

Commit dcdda87

Browse files
authored
Merge pull request microsoft#28243 from Microsoft/containerOnlyRef
Report error requiring references to have composite only if the program is not container only
2 parents 4606a4b + 305303c commit dcdda87

File tree

12 files changed

+149
-17
lines changed

12 files changed

+149
-17
lines changed

src/compiler/program.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2806,7 +2806,11 @@ namespace ts {
28062806
}
28072807
const options = resolvedRef.commandLine.options;
28082808
if (!options.composite) {
2809-
createDiagnosticForReference(parentFile, index, Diagnostics.Referenced_project_0_must_have_setting_composite_Colon_true, ref.path);
2809+
// ok to not have composite if the current program is container only
2810+
const inputs = parent ? parent.commandLine.fileNames : rootNames;
2811+
if (inputs.length) {
2812+
createDiagnosticForReference(parentFile, index, Diagnostics.Referenced_project_0_must_have_setting_composite_Colon_true, ref.path);
2813+
}
28102814
}
28112815
if (ref.prepend) {
28122816
const out = options.outFile || options.out;

src/harness/virtualFileSystemWithWatch.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -988,4 +988,16 @@ interface Array<T> {}`
988988
return this.environmentVariables && this.environmentVariables.get(name) || "";
989989
}
990990
}
991+
992+
export const tsbuildProjectsLocation = "/user/username/projects";
993+
export function getTsBuildProjectFilePath(project: string, file: string) {
994+
return `${tsbuildProjectsLocation}/${project}/${file}`;
995+
}
996+
997+
export function getTsBuildProjectFile(project: string, file: string): File {
998+
return {
999+
path: getTsBuildProjectFilePath(project, file),
1000+
content: Harness.IO.readFile(`${Harness.IO.getWorkspaceRoot()}/tests/projects/${project}/${file}`)!
1001+
};
1002+
}
9911003
}

src/testRunner/unittests/projectReferences.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,10 @@ namespace ts {
147147
},
148148
"/reference": {
149149
files: { "/secondary/b.ts": moduleImporting("../primary/a") },
150-
references: ["../primary"]
150+
references: ["../primary"],
151+
config: {
152+
files: ["b.ts"]
153+
}
151154
}
152155
};
153156
testProjectReferences(spec, "/reference/tsconfig.json", program => {
@@ -156,6 +159,26 @@ namespace ts {
156159
});
157160
});
158161

162+
it("does not error when the referenced project doesn't have composite:true if its a container project", () => {
163+
const spec: TestSpecification = {
164+
"/primary": {
165+
files: { "/primary/a.ts": emptyModule },
166+
references: [],
167+
options: {
168+
composite: false
169+
}
170+
},
171+
"/reference": {
172+
files: { "/secondary/b.ts": moduleImporting("../primary/a") },
173+
references: ["../primary"],
174+
}
175+
};
176+
testProjectReferences(spec, "/reference/tsconfig.json", program => {
177+
const errs = program.getOptionsDiagnostics();
178+
assertNoErrors("Reports an error about 'composite' not being set", errs);
179+
});
180+
});
181+
159182
it("errors when the file list is not exhaustive", () => {
160183
const spec: TestSpecification = {
161184
"/primary": {

src/testRunner/unittests/tsbuildWatchMode.ts

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
namespace ts.tscWatch {
22
export import libFile = TestFSWithWatch.libFile;
3-
function createSolutionBuilder(system: WatchedSystem, rootNames: ReadonlyArray<string>, defaultOptions?: BuildOptions) {
3+
import projectsLocation = TestFSWithWatch.tsbuildProjectsLocation;
4+
import getFilePathInProject = TestFSWithWatch.getTsBuildProjectFilePath;
5+
import getFileFromProject = TestFSWithWatch.getTsBuildProjectFile;
6+
export function createSolutionBuilder(system: WatchedSystem, rootNames: ReadonlyArray<string>, defaultOptions?: BuildOptions) {
47
const host = createSolutionBuilderWithWatchHost(system);
58
return ts.createSolutionBuilder(host, rootNames, defaultOptions || { watch: true });
69
}
@@ -13,7 +16,6 @@ namespace ts.tscWatch {
1316
}
1417

1518
describe("tsbuild-watch program updates", () => {
16-
const projectsLocation = "/user/username/projects";
1719
const project = "sample1";
1820
const enum SubProject {
1921
core = "core",
@@ -24,23 +26,10 @@ namespace ts.tscWatch {
2426
type ReadonlyFile = Readonly<File>;
2527
/** [tsconfig, index] | [tsconfig, index, anotherModule, someDecl] */
2628
type SubProjectFiles = [ReadonlyFile, ReadonlyFile] | [ReadonlyFile, ReadonlyFile, ReadonlyFile, ReadonlyFile];
27-
const root = Harness.IO.getWorkspaceRoot();
28-
2929
function getProjectPath(project: string) {
3030
return `${projectsLocation}/${project}`;
3131
}
3232

33-
function getFilePathInProject(project: string, file: string) {
34-
return `${projectsLocation}/${project}/${file}`;
35-
}
36-
37-
function getFileFromProject(project: string, file: string): File {
38-
return {
39-
path: getFilePathInProject(project, file),
40-
content: Harness.IO.readFile(`${root}/tests/projects/${project}/${file}`)!
41-
};
42-
}
43-
4433
function projectPath(subProject: SubProject) {
4534
return getFilePathInProject(project, subProject);
4635
}

src/testRunner/unittests/tsserverProjectSystem.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10474,6 +10474,55 @@ declare class TestLib {
1047410474
});
1047510475
});
1047610476

10477+
describe("tsserverProjectSystem with tsbuild projects", () => {
10478+
function getProjectFiles(project: string): [File, File] {
10479+
return [
10480+
TestFSWithWatch.getTsBuildProjectFile(project, "tsconfig.json"),
10481+
TestFSWithWatch.getTsBuildProjectFile(project, "index.ts"),
10482+
];
10483+
}
10484+
it("does not error on container only project", () => {
10485+
const project = "container";
10486+
const containerLib = getProjectFiles("container/lib");
10487+
const containerExec = getProjectFiles("container/exec");
10488+
const containerCompositeExec = getProjectFiles("container/compositeExec");
10489+
const containerConfig = TestFSWithWatch.getTsBuildProjectFile(project, "tsconfig.json");
10490+
const files = [libFile, ...containerLib, ...containerExec, ...containerCompositeExec, containerConfig];
10491+
const host = createServerHost(files);
10492+
10493+
// ts build should succeed
10494+
const solutionBuilder = tscWatch.createSolutionBuilder(host, [containerConfig.path], {});
10495+
solutionBuilder.buildAllProjects();
10496+
assert.equal(host.getOutput().length, 0);
10497+
10498+
// Open external project for the folder
10499+
const session = createSession(host);
10500+
const service = session.getProjectService();
10501+
service.openExternalProjects([{
10502+
projectFileName: TestFSWithWatch.getTsBuildProjectFilePath(project, project),
10503+
rootFiles: files.map(f => ({ fileName: f.path })),
10504+
options: {}
10505+
}]);
10506+
checkNumberOfProjects(service, { configuredProjects: 4 });
10507+
files.forEach(f => {
10508+
const args: protocol.FileRequestArgs = {
10509+
file: f.path,
10510+
projectFileName: endsWith(f.path, "tsconfig.json") ? f.path : undefined
10511+
};
10512+
const syntaxDiagnostics = session.executeCommandSeq<protocol.SyntacticDiagnosticsSyncRequest>({
10513+
command: protocol.CommandTypes.SyntacticDiagnosticsSync,
10514+
arguments: args
10515+
}).response;
10516+
assert.deepEqual(syntaxDiagnostics, []);
10517+
const semanticDiagnostics = session.executeCommandSeq<protocol.SemanticDiagnosticsSyncRequest>({
10518+
command: protocol.CommandTypes.SemanticDiagnosticsSync,
10519+
arguments: args
10520+
}).response;
10521+
assert.deepEqual(semanticDiagnostics, []);
10522+
});
10523+
});
10524+
});
10525+
1047710526
describe("tsserverProjectSystem duplicate packages", () => {
1047810527
// Tests that 'moduleSpecifiers.ts' will import from the redirecting file, and not from the file it redirects to, if that can provide a global module specifier.
1047910528
it("works with import fixes", () => {
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
namespace container {
2+
export function getMyConst() {
3+
return myConst;
4+
}
5+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"compilerOptions": {
3+
"outFile": "../built/local/compositeExec.js",
4+
"composite": true
5+
},
6+
"files": [
7+
"index.ts"
8+
],
9+
"references": [
10+
{ "path": "../lib", "prepend": true }
11+
]
12+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
namespace container {
2+
export function getMyConst() {
3+
return myConst;
4+
}
5+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"compilerOptions": {
3+
"outFile": "../built/local/exec.js"
4+
},
5+
"files": [
6+
"index.ts"
7+
],
8+
"references": [
9+
{ "path": "../lib", "prepend": true }
10+
]
11+
}

tests/projects/container/lib/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
namespace container {
2+
export const myConst = 30;
3+
}

0 commit comments

Comments
 (0)