Skip to content

Commit 3988411

Browse files
committed
Store isolated mode in compilation metadata
1 parent 127d9f1 commit 3988411

File tree

3 files changed

+216
-3
lines changed

3 files changed

+216
-3
lines changed

v-next/hardhat/src/internal/builtin-plugins/solidity/build-system/build-system.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ export class SolidityBuildSystemImplementation implements SolidityBuildSystem {
210210
indexedIndividualJobs,
211211
compilationResult,
212212
emitArtifactsResult,
213+
options,
213214
);
214215
}),
215216
);
@@ -391,11 +392,12 @@ export class SolidityBuildSystemImplementation implements SolidityBuildSystem {
391392
const jobHash = await compilationJob.getBuildId();
392393
const cacheResult = this.#compileCache[rootFile];
393394

394-
// If there's no cache for the root file, or the compilation job changed, or using force flag, compile it
395+
// If there's no cache for the root file, or the compilation job changed, or using force flag, or isolated mode changed, compile it
395396
if (
396-
(options?.force ?? false) ||
397+
options?.force === true ||
397398
cacheResult === undefined ||
398-
cacheResult.jobHash !== jobHash
399+
cacheResult.jobHash !== jobHash ||
400+
cacheResult.isolated !== options?.isolated
399401
) {
400402
rootFilesToCompile.add(rootFile);
401403
continue;
@@ -852,6 +854,7 @@ export class SolidityBuildSystemImplementation implements SolidityBuildSystem {
852854
indexedIndividualJobs: Map<string, CompilationJob>,
853855
result: CompilationResult,
854856
emitArtifactsResult: EmitArtifactsResult,
857+
options: BuildOptions | undefined,
855858
): Promise<void> {
856859
const rootFilePaths = result.compilationJob.dependencyGraph
857860
.getRoots()
@@ -884,6 +887,7 @@ export class SolidityBuildSystemImplementation implements SolidityBuildSystem {
884887

885888
this.#compileCache[rootFilePath] = {
886889
jobHash,
890+
isolated: options?.isolated === true,
887891
artifactPaths,
888892
buildInfoPath: emitArtifactsResult.buildInfoPath,
889893
buildInfoOutputPath: emitArtifactsResult.buildInfoOutputPath,

v-next/hardhat/src/internal/builtin-plugins/solidity/build-system/cache.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export type CompileCache = Record<string, CompileCacheEntry>;
1616

1717
export interface CompileCacheEntry {
1818
jobHash: string;
19+
isolated: boolean;
1920
buildInfoPath: string;
2021
buildInfoOutputPath: string;
2122
artifactPaths: string[];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
/* eslint-disable no-restricted-syntax -- test*/
2+
import assert from "node:assert/strict";
3+
import { describe, it } from "node:test";
4+
5+
import { useTestProjectTemplate } from "../resolver/helpers.js";
6+
7+
import { assertFileCounts, getHRE, TestProjectWrapper } from "./helpers.js";
8+
9+
describe("Partial compilation", () => {
10+
describe("Recompiling with changes in isolated mode", () => {
11+
it("it recompiles when changing from non-isolated to isolated", async () => {
12+
await using _project = await useTestProjectTemplate({
13+
name: "test",
14+
version: "1.0.0",
15+
files: {
16+
"contracts/A.sol": `contract A {}`,
17+
"contracts/B.sol": `contract B {}`,
18+
},
19+
});
20+
const hre = await getHRE(_project);
21+
const project = new TestProjectWrapper(_project, hre);
22+
23+
// Compile first time
24+
await project.compile();
25+
const firstSnapshot = await project.getSnapshot();
26+
27+
assertFileCounts(firstSnapshot, 1, 2, 2);
28+
29+
const [buildInfo1] = firstSnapshot.buildInfos;
30+
31+
// The build info should contain A and B
32+
assert.deepEqual(buildInfo1.sources, ["A.sol", "B.sol"]);
33+
34+
// Artifacts should point to the build info
35+
assert.equal(
36+
firstSnapshot.buildIdReferences[
37+
firstSnapshot.artifacts["A.sol"][0].path
38+
],
39+
firstSnapshot.buildInfos[0].buildId,
40+
);
41+
assert.equal(
42+
firstSnapshot.buildIdReferences[
43+
firstSnapshot.artifacts["B.sol"][0].path
44+
],
45+
firstSnapshot.buildInfos[0].buildId,
46+
);
47+
48+
// There should be 1 type definition file per source file
49+
assert.ok(firstSnapshot.typeFiles["A.sol"] !== undefined);
50+
assert.ok(firstSnapshot.typeFiles["B.sol"] !== undefined);
51+
52+
// Recompile with --isolated
53+
await project.compile({ isolated: true });
54+
const secondSnapshot = await project.getSnapshot();
55+
56+
assertFileCounts(secondSnapshot, 2, 2, 2);
57+
58+
const buildInfoA = project.getBuildInfoForSourceFile(
59+
secondSnapshot,
60+
"A.sol",
61+
);
62+
const buildInfoB = project.getBuildInfoForSourceFile(
63+
secondSnapshot,
64+
"B.sol",
65+
);
66+
67+
// Check both build infos are different from the first one
68+
assert.notEqual(buildInfoA.buildId, buildInfo1.buildId);
69+
assert.notEqual(buildInfoB.buildId, buildInfo1.buildId);
70+
71+
// The build info should the respective sources
72+
assert.deepEqual(buildInfoA.sources, ["A.sol"]);
73+
assert.deepEqual(buildInfoB.sources, ["B.sol"]);
74+
75+
// Artifact should point to the new build info
76+
assert.equal(
77+
secondSnapshot.buildIdReferences[
78+
secondSnapshot.artifacts["A.sol"][0].path
79+
],
80+
buildInfoA.buildId,
81+
);
82+
83+
assert.equal(
84+
secondSnapshot.buildIdReferences[
85+
secondSnapshot.artifacts["B.sol"][0].path
86+
],
87+
buildInfoB.buildId,
88+
);
89+
90+
// Artifact files should be new
91+
assert.notDeepEqual(
92+
firstSnapshot.artifacts["A.sol"][0].modificationTime,
93+
secondSnapshot.artifacts["A.sol"][0].modificationTime,
94+
);
95+
assert.notDeepEqual(
96+
firstSnapshot.artifacts["B.sol"][0].modificationTime,
97+
secondSnapshot.artifacts["B.sol"][0].modificationTime,
98+
);
99+
100+
// Typefile should be new
101+
assert.notDeepEqual(
102+
firstSnapshot.typeFiles["A.sol"],
103+
secondSnapshot.typeFiles["A.sol"],
104+
);
105+
assert.notDeepEqual(
106+
firstSnapshot.typeFiles["B.sol"],
107+
secondSnapshot.typeFiles["B.sol"],
108+
);
109+
});
110+
111+
it("it recompiles when changing from isolated to non-isolated", async () => {
112+
await using _project = await useTestProjectTemplate({
113+
name: "test",
114+
version: "1.0.0",
115+
files: {
116+
"contracts/A.sol": `contract A {}`,
117+
"contracts/B.sol": `contract B {}`,
118+
},
119+
});
120+
const hre = await getHRE(_project);
121+
const project = new TestProjectWrapper(_project, hre);
122+
123+
// Compile first time
124+
await project.compile({ isolated: true });
125+
const firstSnapshot = await project.getSnapshot();
126+
127+
assertFileCounts(firstSnapshot, 2, 2, 2);
128+
129+
const buildInfoA = project.getBuildInfoForSourceFile(
130+
firstSnapshot,
131+
"A.sol",
132+
);
133+
const buildInfoB = project.getBuildInfoForSourceFile(
134+
firstSnapshot,
135+
"B.sol",
136+
);
137+
138+
assert.deepEqual(buildInfoA.sources, ["A.sol"]);
139+
assert.deepEqual(buildInfoB.sources, ["B.sol"]);
140+
141+
// Artifacts should point to the build info
142+
assert.equal(
143+
firstSnapshot.buildIdReferences[
144+
firstSnapshot.artifacts["A.sol"][0].path
145+
],
146+
buildInfoA.buildId,
147+
);
148+
assert.equal(
149+
firstSnapshot.buildIdReferences[
150+
firstSnapshot.artifacts["B.sol"][0].path
151+
],
152+
buildInfoB.buildId,
153+
);
154+
155+
// There should be 1 type definition file per source file
156+
assert.ok(firstSnapshot.typeFiles["A.sol"] !== undefined);
157+
assert.ok(firstSnapshot.typeFiles["B.sol"] !== undefined);
158+
159+
// Recompile with --isolated
160+
await project.compile({ isolated: false });
161+
const secondSnapshot = await project.getSnapshot();
162+
163+
assertFileCounts(secondSnapshot, 1, 2, 2);
164+
165+
const [newBuildInfo] = secondSnapshot.buildInfos;
166+
167+
assert.notEqual(buildInfoA.buildId, newBuildInfo.buildId);
168+
assert.notEqual(buildInfoB.buildId, newBuildInfo.buildId);
169+
170+
assert.deepEqual(newBuildInfo.sources, ["A.sol", "B.sol"]);
171+
172+
// Artifact should point to the new build info
173+
assert.equal(
174+
secondSnapshot.buildIdReferences[
175+
secondSnapshot.artifacts["A.sol"][0].path
176+
],
177+
newBuildInfo.buildId,
178+
);
179+
180+
assert.equal(
181+
secondSnapshot.buildIdReferences[
182+
secondSnapshot.artifacts["B.sol"][0].path
183+
],
184+
newBuildInfo.buildId,
185+
);
186+
187+
// Artifact files should be new
188+
assert.notDeepEqual(
189+
firstSnapshot.artifacts["A.sol"][0].modificationTime,
190+
secondSnapshot.artifacts["A.sol"][0].modificationTime,
191+
);
192+
assert.notDeepEqual(
193+
firstSnapshot.artifacts["B.sol"][0].modificationTime,
194+
secondSnapshot.artifacts["B.sol"][0].modificationTime,
195+
);
196+
197+
// Typefile should be new
198+
assert.notDeepEqual(
199+
firstSnapshot.typeFiles["A.sol"],
200+
secondSnapshot.typeFiles["A.sol"],
201+
);
202+
assert.notDeepEqual(
203+
firstSnapshot.typeFiles["B.sol"],
204+
secondSnapshot.typeFiles["B.sol"],
205+
);
206+
});
207+
});
208+
});

0 commit comments

Comments
 (0)