Skip to content

Commit 1dc9206

Browse files
committed
Use deps graphs for invalidation.
1 parent b1e5b39 commit 1dc9206

34 files changed

+1759
-101
lines changed

_test_common/lib/test_phases.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@ Future<void> wait(int milliseconds) =>
1919
Future.delayed(Duration(milliseconds: milliseconds));
2020

2121
void _printOnFailure(LogRecord record) {
22-
printOnFailure('$record');
22+
printOnFailure(
23+
'$record'
24+
'${record.error == null ? '' : ' ${record.error}'}'
25+
'${record.stackTrace == null ? '' : ' ${record.stackTrace}'}',
26+
);
2327
}
2428

2529
/// Runs [builders] in a test environment.

build/lib/src/internal.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export 'library_cycle_graph/asset_deps_loader.dart';
1111
export 'library_cycle_graph/library_cycle.dart';
1212
export 'library_cycle_graph/library_cycle_graph.dart';
1313
export 'library_cycle_graph/library_cycle_graph_loader.dart';
14+
export 'library_cycle_graph/phased_asset_deps.dart';
1415
export 'library_cycle_graph/phased_reader.dart';
1516
export 'library_cycle_graph/phased_value.dart';
1617
export 'state/asset_finder.dart';

build/lib/src/library_cycle_graph/asset_deps.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import 'package:built_collection/built_collection.dart';
66
import 'package:built_value/built_value.dart';
7+
import 'package:built_value/serializer.dart';
78

89
import '../../build.dart' hide Builder;
910

@@ -17,11 +18,15 @@ part 'asset_deps.g.dart';
1718
/// Missing or not-yet-generated sources can be represented by this class: they
1819
/// have no deps.
1920
abstract class AssetDeps implements Built<AssetDeps, AssetDepsBuilder> {
21+
static Serializer<AssetDeps> get serializer => _$assetDepsSerializer;
22+
2023
static final AssetDeps empty = _$AssetDeps._(deps: BuiltSet());
2124

2225
BuiltSet<AssetId> get deps;
2326

2427
factory AssetDeps(Iterable<AssetId> deps) =>
2528
_$AssetDeps._(deps: BuiltSet.of(deps));
29+
factory AssetDeps.build(void Function(AssetDepsBuilder) updates) =
30+
_$AssetDeps;
2631
AssetDeps._();
2732
}

build/lib/src/library_cycle_graph/asset_deps.g.dart

Lines changed: 59 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build/lib/src/library_cycle_graph/asset_deps_loader.dart

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import 'package:analyzer/dart/ast/ast.dart';
77

88
import '../asset/id.dart';
99
import 'asset_deps.dart';
10+
import 'phased_asset_deps.dart';
1011
import 'phased_reader.dart';
1112
import 'phased_value.dart';
1213

@@ -17,6 +18,8 @@ class AssetDepsLoader {
1718
final PhasedReader _reader;
1819

1920
AssetDepsLoader(this._reader);
21+
factory AssetDepsLoader.fromDeps(PhasedAssetDeps deps) =>
22+
_InMemoryAssetDepsLoader(deps);
2023

2124
/// The phase that this loader is reading build state at.
2225
int get phase => _reader.phase;
@@ -57,3 +60,34 @@ class AssetDepsLoader {
5760
return result.build();
5861
}
5962
}
63+
64+
class _InMemoryAssetDepsLoader implements AssetDepsLoader {
65+
final Future<PhasedValue<AssetDeps>> _empty = Future.value(
66+
PhasedValue.fixed(AssetDeps.empty),
67+
);
68+
PhasedAssetDeps phasedAssetDeps;
69+
70+
_InMemoryAssetDepsLoader(this.phasedAssetDeps);
71+
72+
@override
73+
ExpiringValue<AssetDeps> _parse(AssetId id, ExpiringValue<String> content) {
74+
throw UnimplementedError();
75+
}
76+
77+
@override
78+
PhasedReader get _reader => throw UnimplementedError();
79+
80+
@override
81+
Future<PhasedValue<AssetDeps>> load(AssetId id) {
82+
var result = phasedAssetDeps.assetDeps[id];
83+
if (result == null) return _empty;
84+
// TODO(davidmorgan): do what with values that were never read? ...
85+
if (!result.isComplete) {
86+
result = result.followedBy(ExpiringValue(result.values.last.value));
87+
}
88+
return Future.value(result);
89+
}
90+
91+
@override
92+
int get phase => 0xffffffff;
93+
}

build/lib/src/library_cycle_graph/library_cycle.dart

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,18 @@ abstract class LibraryCycle
1919
factory LibraryCycle([void Function(LibraryCycleBuilder) updates]) =
2020
_$LibraryCycle;
2121
LibraryCycle._();
22+
23+
factory LibraryCycle.of(Iterable<AssetId> ids) =>
24+
_$LibraryCycle._(ids: ids.toBuiltSet());
25+
26+
@memoized
27+
AssetId get leastId {
28+
var least = ids.first;
29+
for (var id in ids) {
30+
if (id.compareTo(least) < 0) {
31+
least = id;
32+
}
33+
}
34+
return least;
35+
}
2236
}

build/lib/src/library_cycle_graph/library_cycle.g.dart

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build/lib/src/library_cycle_graph/library_cycle_graph.dart

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import 'package:built_collection/built_collection.dart';
66
import 'package:built_value/built_value.dart';
7+
import 'package:built_value/serializer.dart';
78

89
import '../asset/id.dart';
910
import 'library_cycle.dart';
@@ -13,22 +14,36 @@ part 'library_cycle_graph.g.dart';
1314
/// A directed acyclic graph of [LibraryCycle]s.
1415
abstract class LibraryCycleGraph
1516
implements Built<LibraryCycleGraph, LibraryCycleGraphBuilder> {
17+
static Serializer<LibraryCycleGraph> get serializer =>
18+
_$libraryCycleGraphSerializer;
1619
LibraryCycle get root;
17-
BuiltList<LibraryCycleGraph> get children;
20+
BuiltSet<AssetId> get children;
1821

1922
factory LibraryCycleGraph([void Function(LibraryCycleGraphBuilder) updates]) =
2023
_$LibraryCycleGraph;
2124
LibraryCycleGraph._();
2225

26+
factory LibraryCycleGraph.of(
27+
Iterable<AssetId> root, {
28+
Iterable<AssetId> children = const [],
29+
}) => _$LibraryCycleGraph._(
30+
root: LibraryCycle.of(root),
31+
children: children.toBuiltSet(),
32+
);
33+
2334
/// All subgraphs in the graph, including the root.
24-
Iterable<LibraryCycleGraph> get transitiveGraphs {
35+
Iterable<LibraryCycleGraph> transitiveGraphs({
36+
required LibraryCycleGraph Function(AssetId) lookupGraph,
37+
}) {
2538
final result = Set<LibraryCycleGraph>.identity();
2639
final nextGraphs = [this];
2740

2841
while (nextGraphs.isNotEmpty) {
2942
final graph = nextGraphs.removeLast();
3043
if (result.add(graph)) {
31-
nextGraphs.addAll(graph.children);
44+
for (final child in graph.children) {
45+
nextGraphs.add(lookupGraph(child));
46+
}
3247
}
3348
}
3449

@@ -40,8 +55,10 @@ abstract class LibraryCycleGraph
4055
// graph rather than being expanded into an explicit set of nodes. So, remove
4156
// uses of this. If in the end it's still needed, investigate if it needs to
4257
// be optimized.
43-
Iterable<AssetId> get transitiveDeps sync* {
44-
for (final graph in transitiveGraphs) {
58+
Iterable<AssetId> transitiveDeps({
59+
required LibraryCycleGraph Function(AssetId) lookupGraph,
60+
}) sync* {
61+
for (final graph in transitiveGraphs(lookupGraph: lookupGraph)) {
4562
yield* graph.root.ids;
4663
}
4764
}

build/lib/src/library_cycle_graph/library_cycle_graph.g.dart

Lines changed: 80 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)