Skip to content

Commit 989e42f

Browse files
jensjohacommit-bot@chromium.org
authored andcommitted
[CFE] Incremental compiler and part as entry
This CL fixes the incremental compiler in the case where it gets a part as an entry point. Change-Id: I79f1735e0056f259500e2ef52d9b23047f2b812f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/178999 Commit-Queue: Jens Johansen <[email protected]> Reviewed-by: Johnni Winther <[email protected]>
1 parent 37369b3 commit 989e42f

14 files changed

+274
-23
lines changed

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

Lines changed: 79 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,19 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
230230
Set<Uri> invalidatedUris = this.invalidatedUris.toSet();
231231
invalidateNotKeptUserBuilders(invalidatedUris);
232232
ReusageResult reusedResult =
233-
computeReusedLibraries(invalidatedUris, uriTranslator);
233+
computeReusedLibraries(invalidatedUris, uriTranslator, entryPoints);
234+
235+
// Use the reused libraries to re-write entry-points.
236+
if (reusedResult.arePartsUsedAsEntryPoints()) {
237+
for (int i = 0; i < entryPoints.length; i++) {
238+
Uri entryPoint = entryPoints[i];
239+
Uri redirect =
240+
reusedResult.getLibraryUriForPartUsedAsEntryPoint(entryPoint);
241+
if (redirect != null) {
242+
entryPoints[i] = redirect;
243+
}
244+
}
245+
}
234246

235247
// Experimental invalidation initialization (e.g. figure out if we can).
236248
ExperimentalInvalidation experimentalInvalidation =
@@ -1440,18 +1452,26 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
14401452
/// any saved component problems for such builders.
14411453
List<Library> computeTransitiveClosure(
14421454
List<Library> inputLibraries,
1443-
List<Uri> entries,
1455+
List<Uri> entryPoints,
14441456
List<LibraryBuilder> reusedLibraries,
14451457
ClassHierarchy hierarchy,
14461458
UriTranslator uriTranslator,
14471459
Map<Uri, Source> uriToSource,
14481460
[List<Library> inputLibrariesFiltered]) {
14491461
List<Library> result = <Library>[];
1462+
Map<Uri, Uri> partUriToLibraryImportUri = <Uri, Uri>{};
14501463
Map<Uri, Library> libraryMap = <Uri, Library>{};
14511464
Map<Uri, Library> potentiallyReferencedLibraries = <Uri, Library>{};
14521465
Map<Uri, Library> potentiallyReferencedInputLibraries = <Uri, Library>{};
14531466
for (Library library in inputLibraries) {
14541467
libraryMap[library.importUri] = library;
1468+
if (library.parts.isNotEmpty) {
1469+
for (int partIndex = 0; partIndex < library.parts.length; partIndex++) {
1470+
LibraryPart part = library.parts[partIndex];
1471+
Uri partUri = getPartUri(library.importUri, part);
1472+
partUriToLibraryImportUri[partUri] = library.importUri;
1473+
}
1474+
}
14551475
if (library.importUri.scheme == "dart") {
14561476
result.add(library);
14571477
inputLibrariesFiltered?.add(library);
@@ -1460,9 +1480,6 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
14601480
potentiallyReferencedInputLibraries[library.importUri] = library;
14611481
}
14621482
}
1463-
1464-
List<Uri> worklist = <Uri>[];
1465-
worklist.addAll(entries);
14661483
for (LibraryBuilder libraryBuilder in reusedLibraries) {
14671484
if (libraryBuilder.importUri.scheme == "dart" &&
14681485
!libraryBuilder.isSynthetic) {
@@ -1473,6 +1490,19 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
14731490
libraryMap[libraryBuilder.importUri] = lib;
14741491
}
14751492

1493+
List<Uri> worklist = <Uri>[];
1494+
for (Uri entry in entryPoints) {
1495+
if (libraryMap.containsKey(entry)) {
1496+
worklist.add(entry);
1497+
} else {
1498+
// If the entry is a part redirect to the "main" entry.
1499+
Uri partTranslation = partUriToLibraryImportUri[entry];
1500+
if (partTranslation != null) {
1501+
worklist.add(partTranslation);
1502+
}
1503+
}
1504+
}
1505+
14761506
LibraryGraph graph = new LibraryGraph(libraryMap);
14771507
Set<Uri> partsUsed = new Set<Uri>();
14781508
while (worklist.isNotEmpty && potentiallyReferencedLibraries.isNotEmpty) {
@@ -1928,8 +1958,8 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
19281958
}
19291959

19301960
/// Internal method.
1931-
ReusageResult computeReusedLibraries(
1932-
Set<Uri> invalidatedUris, UriTranslator uriTranslator) {
1961+
ReusageResult computeReusedLibraries(Set<Uri> invalidatedUris,
1962+
UriTranslator uriTranslator, List<Uri> entryPoints) {
19331963
Set<Uri> seenUris = new Set<Uri>();
19341964
List<LibraryBuilder> reusedLibraries = <LibraryBuilder>[];
19351965
for (int i = 0; i < platformBuilders.length; i++) {
@@ -1938,14 +1968,15 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
19381968
reusedLibraries.add(builder);
19391969
}
19401970
if (userCode == null && userBuilders == null) {
1941-
return new ReusageResult(const {}, const {}, false, reusedLibraries);
1971+
return new ReusageResult.reusedLibrariesOnly(reusedLibraries);
19421972
}
19431973
bool invalidatedBecauseOfPackageUpdate = false;
19441974
Set<LibraryBuilder> directlyInvalidated = new Set<LibraryBuilder>();
19451975
Set<LibraryBuilder> notReusedLibraries = new Set<LibraryBuilder>();
19461976

19471977
// Maps all non-platform LibraryBuilders from their import URI.
19481978
Map<Uri, LibraryBuilder> builders = <Uri, LibraryBuilder>{};
1979+
Map<Uri, LibraryBuilder> partUriToParent = <Uri, LibraryBuilder>{};
19491980

19501981
// Invalidated URIs translated back to their import URI (package:, dart:,
19511982
// etc.).
@@ -1989,7 +2020,10 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
19892020
invalidatedImportUris.add(uri);
19902021
}
19912022
if (libraryBuilder is SourceLibraryBuilder) {
2023+
// TODO(jensj): This shouldn't be possible anymore.
19922024
for (LibraryBuilder part in libraryBuilder.parts) {
2025+
partUriToParent[part.importUri] = libraryBuilder;
2026+
partUriToParent[part.fileUri] = libraryBuilder;
19932027
if (isInvalidated(part.importUri, part.fileUri)) {
19942028
invalidatedImportUris.add(part.importUri);
19952029
builders[part.importUri] = part;
@@ -2000,6 +2034,8 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
20002034
Uri partUri = getPartUri(libraryBuilder.importUri, part);
20012035
Uri fileUri = getPartFileUri(
20022036
libraryBuilder.library.fileUri, part, uriTranslator);
2037+
partUriToParent[partUri] = libraryBuilder;
2038+
partUriToParent[fileUri] = libraryBuilder;
20032039

20042040
if (isInvalidated(partUri, fileUri)) {
20052041
invalidatedImportUris.add(partUri);
@@ -2078,8 +2114,21 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
20782114
reusedLibraries.add(builder);
20792115
}
20802116

2081-
return new ReusageResult(notReusedLibraries, directlyInvalidated,
2082-
invalidatedBecauseOfPackageUpdate, reusedLibraries);
2117+
ReusageResult result = new ReusageResult(
2118+
notReusedLibraries,
2119+
directlyInvalidated,
2120+
invalidatedBecauseOfPackageUpdate,
2121+
reusedLibraries);
2122+
2123+
for (Uri entryPoint in entryPoints) {
2124+
LibraryBuilder parent = partUriToParent[entryPoint];
2125+
if (reusedLibraries.contains(parent)) {
2126+
result.registerLibraryUriForPartUsedAsEntryPoint(
2127+
entryPoint, parent.importUri);
2128+
}
2129+
}
2130+
2131+
return result;
20832132
}
20842133

20852134
@override
@@ -2153,13 +2202,32 @@ class ReusageResult {
21532202
final Set<LibraryBuilder> directlyInvalidated;
21542203
final bool invalidatedBecauseOfPackageUpdate;
21552204
final List<LibraryBuilder> reusedLibraries;
2205+
final Map<Uri, Uri> _reusedLibrariesPartsToParentForEntryPoints;
2206+
2207+
ReusageResult.reusedLibrariesOnly(this.reusedLibraries)
2208+
: notReusedLibraries = const {},
2209+
directlyInvalidated = const {},
2210+
invalidatedBecauseOfPackageUpdate = false,
2211+
_reusedLibrariesPartsToParentForEntryPoints = const {};
21562212

21572213
ReusageResult(this.notReusedLibraries, this.directlyInvalidated,
21582214
this.invalidatedBecauseOfPackageUpdate, this.reusedLibraries)
2159-
: assert(notReusedLibraries != null),
2215+
: _reusedLibrariesPartsToParentForEntryPoints = {},
2216+
assert(notReusedLibraries != null),
21602217
assert(directlyInvalidated != null),
21612218
assert(invalidatedBecauseOfPackageUpdate != null),
21622219
assert(reusedLibraries != null);
2220+
2221+
void registerLibraryUriForPartUsedAsEntryPoint(
2222+
Uri entryPoint, Uri importUri) {
2223+
_reusedLibrariesPartsToParentForEntryPoints[entryPoint] = importUri;
2224+
}
2225+
2226+
bool arePartsUsedAsEntryPoints() =>
2227+
_reusedLibrariesPartsToParentForEntryPoints.isNotEmpty;
2228+
2229+
Uri getLibraryUriForPartUsedAsEntryPoint(Uri entryPoint) =>
2230+
_reusedLibrariesPartsToParentForEntryPoints[entryPoint];
21632231
}
21642232

21652233
class ExperimentalInvalidation {

pkg/front_end/test/incremental_load_from_dill_suite.dart

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -831,18 +831,20 @@ class NewWorldTest {
831831
}
832832

833833
if (!noFullComponent) {
834-
List<Library> entryLib = component.libraries
835-
.where((Library lib) =>
836-
entries.contains(lib.importUri) ||
837-
entries.contains(lib.fileUri))
838-
.toList();
839-
if (entryLib.length != entries.length) {
840-
return new Result<TestData>(
841-
data,
842-
UnexpectedEntryToLibraryCount,
843-
"Expected the entries to become libraries. "
844-
"Got ${entryLib.length} libraries for the expected "
845-
"${entries.length} entries.");
834+
if (world["checkEntries"] != false) {
835+
List<Library> entryLib = component.libraries
836+
.where((Library lib) =>
837+
entries.contains(lib.importUri) ||
838+
entries.contains(lib.fileUri))
839+
.toList();
840+
if (entryLib.length != entries.length) {
841+
return new Result<TestData>(
842+
data,
843+
UnexpectedEntryToLibraryCount,
844+
"Expected the entries to become libraries. "
845+
"Got ${entryLib.length} libraries for the expected "
846+
"${entries.length} entries.");
847+
}
846848
}
847849
}
848850
if (compiler.initializedFromDill != expectInitializeFromDill) {
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Copyright (c) 2021, 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+
type: newworld
6+
worlds:
7+
- entry: main.dart
8+
checkEntries: false
9+
sources:
10+
main.dart: |
11+
part of 'lib.dart';
12+
partMethod() {}
13+
lib.dart: |
14+
part 'main.dart';
15+
main() {}
16+
expectedLibraryCount: 1
17+
18+
- entry: main.dart
19+
checkEntries: false
20+
worldType: updated
21+
expectInitializeFromDill: false
22+
invalidate:
23+
- main.dart
24+
expectedLibraryCount: 1
25+
26+
- entry: main.dart
27+
checkEntries: false
28+
worldType: updated
29+
expectInitializeFromDill: false
30+
invalidate:
31+
- lib.dart
32+
expectedLibraryCount: 1
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
main = lib::main;
2+
library from "org-dartlang-test:///lib.dart" as lib {
3+
4+
part main.dart;
5+
static method main() → dynamic {}
6+
static method /* from org-dartlang-test:///main.dart */ partMethod() → dynamic {}
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
main = lib::main;
2+
library from "org-dartlang-test:///lib.dart" as lib {
3+
4+
part main.dart;
5+
static method main() → dynamic {}
6+
static method /* from org-dartlang-test:///main.dart */ partMethod() → dynamic {}
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
main = lib::main;
2+
library from "org-dartlang-test:///lib.dart" as lib {
3+
4+
part main.dart;
5+
static method main() → dynamic {}
6+
static method /* from org-dartlang-test:///main.dart */ partMethod() → dynamic {}
7+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Copyright (c) 2021, 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+
type: newworld
6+
worlds:
7+
- entry: package:foo/main.dart
8+
checkEntries: false
9+
sources:
10+
.packages: |
11+
foo:.
12+
main.dart: |
13+
part of 'lib.dart';
14+
partMethod() {}
15+
lib.dart: |
16+
part 'main.dart';
17+
main() {}
18+
expectedLibraryCount: 1
19+
20+
- entry: package:foo/main.dart
21+
checkEntries: false
22+
worldType: updated
23+
expectInitializeFromDill: false
24+
invalidate:
25+
- main.dart
26+
expectedLibraryCount: 1
27+
28+
- entry: package:foo/main.dart
29+
checkEntries: false
30+
worldType: updated
31+
expectInitializeFromDill: false
32+
invalidate:
33+
- lib.dart
34+
expectedLibraryCount: 1
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
main = lib::main;
2+
library from "package:foo/lib.dart" as lib {
3+
4+
part main.dart;
5+
static method main() → dynamic {}
6+
static method /* from org-dartlang-test:///main.dart */ partMethod() → dynamic {}
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
main = lib::main;
2+
library from "package:foo/lib.dart" as lib {
3+
4+
part main.dart;
5+
static method main() → dynamic {}
6+
static method /* from org-dartlang-test:///main.dart */ partMethod() → dynamic {}
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
main = lib::main;
2+
library from "package:foo/lib.dart" as lib {
3+
4+
part main.dart;
5+
static method main() → dynamic {}
6+
static method /* from org-dartlang-test:///main.dart */ partMethod() → dynamic {}
7+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Copyright (c) 2021, 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+
type: newworld
6+
worlds:
7+
- entry: main.dart
8+
warnings: true
9+
checkEntries: false
10+
sources:
11+
.packages: |
12+
foo:.
13+
main.dart: |
14+
part of 'lib.dart';
15+
partMethod() {}
16+
lib.dart: |
17+
part 'main.dart';
18+
main() {}
19+
expectedLibraryCount: 1
20+
21+
- entry: main.dart
22+
warnings: true
23+
checkEntries: false
24+
worldType: updated
25+
expectInitializeFromDill: false
26+
invalidate:
27+
- main.dart
28+
expectedLibraryCount: 1
29+
30+
- entry: main.dart
31+
warnings: true
32+
checkEntries: false
33+
worldType: updated
34+
expectInitializeFromDill: false
35+
invalidate:
36+
- lib.dart
37+
expectedLibraryCount: 1
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
main = lib::main;
2+
//
3+
// Problems in component:
4+
//
5+
// org-dartlang-test:///main.dart: Warning: Interpreting this as package URI, 'package:foo/main.dart'.
6+
//
7+
library from "package:foo/lib.dart" as lib {
8+
9+
part main.dart;
10+
static method main() → dynamic {}
11+
static method /* from org-dartlang-test:///main.dart */ partMethod() → dynamic {}
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
main = lib::main;
2+
//
3+
// Problems in component:
4+
//
5+
// org-dartlang-test:///main.dart: Warning: Interpreting this as package URI, 'package:foo/main.dart'.
6+
//
7+
library from "package:foo/lib.dart" as lib {
8+
9+
part main.dart;
10+
static method main() → dynamic {}
11+
static method /* from org-dartlang-test:///main.dart */ partMethod() → dynamic {}
12+
}

0 commit comments

Comments
 (0)