Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit a86b864

Browse files
jensjohacommit-bot@chromium.org
authored andcommitted
Handle updated .packages in incremental compiler
Change-Id: I6de6cb643b14b14ce54944f57b9e15f502750206 Reviewed-on: https://dart-review.googlesource.com/49901 Reviewed-by: Peter von der Ahé <[email protected]> Commit-Queue: Jens Johansen <[email protected]>
1 parent f555ae5 commit a86b864

File tree

8 files changed

+275
-50
lines changed

8 files changed

+275
-50
lines changed

pkg/front_end/lib/src/base/processed_options.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,11 @@ class ProcessedOptions {
392392
///
393393
/// This is an asynchronous method since file system operations may be
394394
/// required to locate/read the packages file as well as SDK metadata.
395-
Future<UriTranslatorImpl> getUriTranslator() async {
395+
Future<UriTranslatorImpl> getUriTranslator({bool bypassCache: false}) async {
396+
if (bypassCache) {
397+
_uriTranslator = null;
398+
_packages = null;
399+
}
396400
if (_uriTranslator == null) {
397401
ticker.logMs("Started building UriTranslator");
398402
var libraries = await _computeLibrarySpecification();

pkg/front_end/lib/src/fasta/incremental_compiler.dart

Lines changed: 38 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -63,22 +63,27 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
6363
entryPoint ??= context.options.inputs.single;
6464
return context.runInContext<Future<Component>>((CompilerContext c) async {
6565
IncrementalCompilerData data = new IncrementalCompilerData();
66-
if (dillLoadedData == null) {
67-
UriTranslator uriTranslator = await c.options.getUriTranslator();
68-
ticker.logMs("Read packages file");
6966

67+
// TODO(jensj): We should only bypass the cache if .packages has been
68+
// invalidated, but Flutter does not currently invalidate .packages.
69+
UriTranslator uriTranslator =
70+
await c.options.getUriTranslator(bypassCache: true);
71+
ticker.logMs("Read packages file");
72+
73+
if (dillLoadedData == null) {
7074
List<int> summaryBytes = await c.options.loadSdkSummaryBytes();
7175
int bytesLength = prepareSummary(summaryBytes, uriTranslator, c, data);
7276
if (initializeFromDillUri != null) {
7377
try {
74-
bytesLength += await initializeFromDill(summaryBytes, c, data);
78+
bytesLength +=
79+
await initializeFromDill(summaryBytes, uriTranslator, c, data);
7580
} catch (e) {
7681
// We might have loaded x out of y libraries into the component.
7782
// To avoid any unforeseen problems start over.
7883
bytesLength = prepareSummary(summaryBytes, uriTranslator, c, data);
7984
}
8085
}
81-
appendLibraries(data, bytesLength, uriTranslator);
86+
appendLibraries(data, bytesLength);
8287

8388
try {
8489
await dillLoadedData.buildOutlines();
@@ -89,7 +94,7 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
8994
initializedFromDill = false;
9095
data.reset();
9196
bytesLength = prepareSummary(summaryBytes, uriTranslator, c, data);
92-
appendLibraries(data, bytesLength, uriTranslator);
97+
appendLibraries(data, bytesLength);
9398
await dillLoadedData.buildOutlines();
9499
}
95100
summaryBytes = null;
@@ -112,7 +117,7 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
112117
}
113118

114119
List<LibraryBuilder> reusedLibraries =
115-
computeReusedLibraries(invalidatedUris);
120+
computeReusedLibraries(invalidatedUris, uriTranslator);
116121
Set<Uri> reusedLibraryUris =
117122
new Set<Uri>.from(reusedLibraries.map((b) => b.uri));
118123
for (Uri uri in new Set<Uri>.from(dillLoadedData.loader.builders.keys)
@@ -128,7 +133,7 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
128133

129134
KernelIncrementalTarget userCodeOld = userCode;
130135
userCode = new KernelIncrementalTarget(
131-
c.fileSystem, false, dillLoadedData, dillLoadedData.uriTranslator,
136+
c.fileSystem, false, dillLoadedData, uriTranslator,
132137
uriToSource: c.uriToSource);
133138

134139
for (LibraryBuilder library in reusedLibraries) {
@@ -258,7 +263,10 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
258263
}
259264

260265
// This procedure will try to load the dill file and will crash if it cannot.
261-
Future<int> initializeFromDill(List<int> summaryBytes, CompilerContext c,
266+
Future<int> initializeFromDill(
267+
List<int> summaryBytes,
268+
UriTranslator uriTranslator,
269+
CompilerContext c,
262270
IncrementalCompilerData data) async {
263271
int bytesLength = 0;
264272
FileSystemEntity entity =
@@ -277,6 +285,20 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
277285
new BinaryBuilder(initializationBytes, disableLazyReading: true)
278286
.readComponent(data.component);
279287

288+
// Check the any package-urls still point to the same file
289+
// (e.g. the package still exists and hasn't been updated).
290+
for (Library lib in data.component.libraries) {
291+
if (lib.importUri.scheme == "package" &&
292+
uriTranslator.translate(lib.importUri, false) != lib.fileUri) {
293+
// Package has been removed or updated.
294+
// This library should be thrown away.
295+
// Everything that depends on it should be thrown away.
296+
// TODO(jensj): Anything that doesn't depend on it can be kept.
297+
// For now just don't initialize from this dill.
298+
throw "Changed package";
299+
}
300+
}
301+
280302
initializedFromDill = true;
281303
bytesLength += initializationBytes.length;
282304
for (Library lib in data.component.libraries) {
@@ -294,27 +316,16 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
294316
return bytesLength;
295317
}
296318

297-
void appendLibraries(IncrementalCompilerData data, int bytesLength,
298-
UriTranslator uriTranslator) {
319+
void appendLibraries(IncrementalCompilerData data, int bytesLength) {
299320
if (data.component != null) {
300-
List<Library> keepLibraries = <Library>[];
301-
for (Library lib in data.component.libraries) {
302-
if (lib.importUri.scheme != "package" ||
303-
uriTranslator.translate(lib.importUri, false) != null) {
304-
keepLibraries.add(lib);
305-
}
306-
}
307-
data.component.libraries
308-
..clear()
309-
..addAll(keepLibraries);
310-
311321
dillLoadedData.loader
312322
.appendLibraries(data.component, byteCount: bytesLength);
313323
}
314324
ticker.logMs("Appended libraries");
315325
}
316326

317-
List<LibraryBuilder> computeReusedLibraries(Iterable<Uri> invalidatedUris) {
327+
List<LibraryBuilder> computeReusedLibraries(
328+
Iterable<Uri> invalidatedUris, UriTranslator uriTranslator) {
318329
if (userCode == null && userBuilders == null) {
319330
return <LibraryBuilder>[];
320331
}
@@ -338,7 +349,10 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
338349
invalidatedFileUris.contains(library.fileUri)) ||
339350
(library is DillLibraryBuilder &&
340351
uri != library.library.fileUri &&
341-
invalidatedFileUris.contains(library.library.fileUri))) {
352+
invalidatedFileUris.contains(library.library.fileUri)) ||
353+
(library.uri.scheme == "package" &&
354+
uriTranslator.translate(library.uri, false) !=
355+
library.target.fileUri)) {
342356
invalidatedImportUris.add(uri);
343357
}
344358
if (!recursive) return;

pkg/front_end/test/incremental_dart2js_load_from_dill_test.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ void testDart2jsCompile() async {
6868
checkIsEqual(normalDillData, initializedDillData);
6969

7070
// Also try without invalidating anything.
71+
stopwatch.reset();
7172
initializeResult = await initializedCompile(
7273
dart2jsUrl, fullDillFromInitialized, initializeWith, []);
7374
Expect.equals(initializeExpect, initializeResult);

pkg/front_end/test/incremental_load_from_dill_test.dart

Lines changed: 52 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -174,15 +174,33 @@ void newWorldTest(bool strong, List worlds) async {
174174
await new File.fromUri(platformUri).readAsBytes();
175175

176176
List<int> newestWholeComponent;
177+
MemoryFileSystem fs;
178+
Map<String, String> sourceFiles;
179+
CompilerOptions options;
180+
TestIncrementalCompiler compiler;
177181
for (var world in worlds) {
178-
MemoryFileSystem fs = new MemoryFileSystem(base);
182+
bool brandNewWorld = true;
183+
if (world["worldType"] == "updated") {
184+
brandNewWorld = false;
185+
}
186+
187+
if (brandNewWorld) {
188+
fs = new MemoryFileSystem(base);
189+
}
179190
fs.entityForUri(sdkSummary).writeAsBytesSync(sdkSummaryData);
180191
bool expectInitializeFromDill = false;
181192
if (newestWholeComponent != null && newestWholeComponent.isNotEmpty) {
182193
fs.entityForUri(initializeFrom).writeAsBytesSync(newestWholeComponent);
183194
expectInitializeFromDill = true;
184195
}
185-
Map<String, String> sourceFiles = world["sources"];
196+
if (world["expectInitializeFromDill"] != null) {
197+
expectInitializeFromDill = world["expectInitializeFromDill"];
198+
}
199+
if (brandNewWorld) {
200+
sourceFiles = new Map<String, String>.from(world["sources"]);
201+
} else {
202+
sourceFiles.addAll(world["sources"]);
203+
}
186204
Uri packagesUri;
187205
for (String filename in sourceFiles.keys) {
188206
String data = sourceFiles[filename] ?? "";
@@ -194,12 +212,14 @@ void newWorldTest(bool strong, List worlds) async {
194212
fs.entityForUri(uri).writeAsStringSync(data);
195213
}
196214

197-
CompilerOptions options = getOptions(strong);
198-
options.fileSystem = fs;
199-
options.sdkRoot = null;
200-
options.sdkSummary = sdkSummary;
201-
if (packagesUri != null) {
202-
options.packagesFileUri = packagesUri;
215+
if (brandNewWorld) {
216+
options = getOptions(strong);
217+
options.fileSystem = fs;
218+
options.sdkRoot = null;
219+
options.sdkSummary = sdkSummary;
220+
if (packagesUri != null) {
221+
options.packagesFileUri = packagesUri;
222+
}
203223
}
204224
bool gotError = false;
205225
List<String> formattedErrors = <String>[];
@@ -218,8 +238,9 @@ void newWorldTest(bool strong, List worlds) async {
218238
};
219239

220240
Uri entry = base.resolve(world["entry"]);
221-
TestIncrementalCompiler compiler =
222-
new TestIncrementalCompiler(options, entry, initializeFrom);
241+
if (brandNewWorld) {
242+
compiler = new TestIncrementalCompiler(options, entry, initializeFrom);
243+
}
223244

224245
if (world["invalidate"] != null) {
225246
for (var filename in world["invalidate"]) {
@@ -228,7 +249,7 @@ void newWorldTest(bool strong, List worlds) async {
228249
}
229250

230251
Stopwatch stopwatch = new Stopwatch()..start();
231-
Component component = await compiler.computeDelta();
252+
Component component = await compiler.computeDelta(fullComponent: true);
232253
if (world["errors"] == true && !gotError) {
233254
throw "Expected error, but didn't get any.";
234255
} else if (world["errors"] != true && gotError) {
@@ -254,19 +275,27 @@ void newWorldTest(bool strong, List worlds) async {
254275
throw "Expected that initializedFromDill would be "
255276
"$expectInitializeFromDill but was ${compiler.initializedFromDill}";
256277
}
257-
if (world["invalidate"] != null) {
258-
Expect.equals(world["invalidate"].length,
259-
compiler.invalidatedImportUrisForTesting.length);
260-
List expectedInvalidatedUri = world["expectedInvalidatedUri"];
261-
if (expectedInvalidatedUri != null) {
262-
Expect.setEquals(
263-
expectedInvalidatedUri
264-
.map((s) => Uri.parse(substituteVariables(s, base))),
265-
compiler.invalidatedImportUrisForTesting);
278+
if (world["checkInvalidatedFiles"] != false) {
279+
if (world["invalidate"] != null) {
280+
Expect.equals(world["invalidate"].length,
281+
compiler.invalidatedImportUrisForTesting.length);
282+
List expectedInvalidatedUri = world["expectedInvalidatedUri"];
283+
if (expectedInvalidatedUri != null) {
284+
Expect.setEquals(
285+
expectedInvalidatedUri
286+
.map((s) => Uri.parse(substituteVariables(s, base))),
287+
compiler.invalidatedImportUrisForTesting);
288+
}
289+
} else {
290+
Expect.isNull(compiler.invalidatedImportUrisForTesting);
291+
Expect.isNull(world["expectedInvalidatedUri"]);
266292
}
267-
} else {
268-
Expect.isNull(compiler.invalidatedImportUrisForTesting);
269-
Expect.isNull(world["expectedInvalidatedUri"]);
293+
}
294+
295+
{
296+
Component component2 = await compiler.computeDelta(fullComponent: true);
297+
List<int> thisWholeComponent = serializeComponent(component2);
298+
checkIsEqual(newestWholeComponent, thisWholeComponent);
270299
}
271300
}
272301
}

pkg/front_end/testcases/incremental_initialize_from_dill/disappearing_package.yaml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,11 @@ worlds:
2525
.packages: dummy:${outDirUri}
2626
expectedLibraryCount: 2
2727
- entry: main.dart
28-
invalidate:
29-
- main.dart
28+
# TODO(jensj): For now we don't initialize from dill when a package was
29+
# changed.
30+
#invalidate:
31+
# - main.dart
32+
expectInitializeFromDill: false
3033
sources:
3134
main.dart: |
3235
main() {
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
2+
# for details. All rights reserved. Use of this source code is governed by a
3+
# BSD-style license that can be found in the LICENSE.md file.
4+
5+
# Compile an application with a package and use it.
6+
# Then update the package from .packages.
7+
# The old package is still included in the dill file we initialize from,
8+
# but shouldn't cause trouble, nor be included in the output.
9+
10+
type: newworld
11+
strong: false
12+
worlds:
13+
- entry: main.dart
14+
sources:
15+
main.dart: |
16+
import "package:dummy/b.dart";
17+
main() {
18+
print("hello");
19+
b();
20+
}
21+
package_0.1.0/a.dart: |
22+
a() {
23+
la1();
24+
}
25+
la1() {
26+
print("v0.1.0");
27+
}
28+
package_0.1.0/b.dart: |
29+
import "a.dart";
30+
b() {
31+
a();
32+
}
33+
.packages: dummy:${outDirUri}package_0.1.0
34+
expectedLibraryCount: 3
35+
- entry: main.dart
36+
# TODO(jensj): For now we don't initialize from dill when a package was
37+
# changed.
38+
#invalidate:
39+
# - main.dart
40+
expectInitializeFromDill: false
41+
sources:
42+
main.dart: |
43+
import "package:dummy/b.dart";
44+
main() {
45+
print("hello");
46+
b();
47+
}
48+
package_0.1.0/a.dart: |
49+
a() {
50+
la1();
51+
}
52+
la1() {
53+
print("v0.1.0");
54+
}
55+
package_0.1.0/b.dart: |
56+
import "a.dart";
57+
b() {
58+
a();
59+
}
60+
package_0.1.1/b.dart: |
61+
b() {
62+
print("hello from v0.1.1");
63+
}
64+
.packages: dummy:${outDirUri}package_0.1.1
65+
expectedLibraryCount: 2

0 commit comments

Comments
 (0)