Skip to content

Commit d3258e4

Browse files
authored
Stop passing reader and writer via BuildDefinition. (#3922)
Refactor `BuildCacheAssetProvider` to `GeneratedFileHider`.
1 parent 4894f0b commit d3258e4

14 files changed

+210
-228
lines changed

build/lib/src/internal.dart

+1
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@ export 'state/asset_finder.dart';
1010
export 'state/asset_path_provider.dart';
1111
export 'state/filesystem.dart';
1212
export 'state/filesystem_cache.dart';
13+
export 'state/generated_asset_hider.dart';
1314
export 'state/reader_state.dart';
1415
export 'state/reader_writer.dart';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright (c) 2025, 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 file.
4+
5+
import '../asset/id.dart';
6+
7+
/// Optionally modifies the storage location of assets.
8+
///
9+
/// `AssetGraph` provides an implementation of this interface that moves
10+
/// "hidden" generated files to the "build cache" path under `rootPackage`.
11+
abstract interface class GeneratedAssetHider {
12+
/// Returns [id] or an updated [id].
13+
AssetId maybeHide(AssetId id, String rootPackage);
14+
}
15+
16+
/// [GeneratedAssetHider] that does nothing.
17+
class NoopGeneratedAssetHider implements GeneratedAssetHider {
18+
const NoopGeneratedAssetHider();
19+
20+
@override
21+
AssetId maybeHide(AssetId id, String _) => id;
22+
}

build/lib/src/state/reader_state.dart

+52-19
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,46 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5+
import 'package:build_runner_core/build_runner_core.dart';
6+
57
import '../asset/reader.dart';
8+
import '../asset/writer.dart';
69
import 'asset_finder.dart';
710
import 'asset_path_provider.dart';
811
import 'filesystem.dart';
912
import 'filesystem_cache.dart';
13+
import 'generated_asset_hider.dart';
1014
import 'reader_writer.dart';
1115

1216
/// Provides access to the state backing an [AssetReader].
1317
extension AssetReaderStateExtension on AssetReader {
14-
/// Returns a new instance with optionally updated [cache].
18+
/// Returns a new instance with optionally updated [cache] and/or [generatedAssetHider].
1519
AssetReaderWriter copyWith({
16-
AssetPathProvider? assetPathProvider,
1720
FilesystemCache? cache,
21+
GeneratedAssetHider? generatedAssetHider,
1822
}) {
1923
_requireIsAssetReaderState();
2024
return (this as AssetReaderState).copyWith(
21-
assetPathProvider: assetPathProvider,
2225
cache: cache,
26+
generatedAssetHider: generatedAssetHider,
2327
);
2428
}
2529

30+
AssetFinder get assetFinder {
31+
_requireIsAssetReaderState();
32+
return (this as AssetReaderState).assetFinder;
33+
}
34+
35+
AssetPathProvider get assetPathProvider {
36+
_requireIsAssetReaderState();
37+
return (this as AssetReaderState).assetPathProvider;
38+
}
39+
40+
GeneratedAssetHider get generatedAssetHider {
41+
_requireIsAssetReaderState();
42+
return (this as AssetReaderState).generatedAssetHider;
43+
}
44+
2645
Filesystem get filesystem {
2746
_requireIsAssetReaderState();
2847
return (this as AssetReaderState).filesystem;
@@ -33,14 +52,25 @@ extension AssetReaderStateExtension on AssetReader {
3352
return (this as AssetReaderState).cache;
3453
}
3554

36-
AssetFinder get assetFinder {
37-
_requireIsAssetReaderState();
38-
return (this as AssetReaderState).assetFinder;
55+
/// Throws if `this` is not an [AssetReaderState].
56+
void _requireIsAssetReaderState() {
57+
if (this is! AssetReaderState) {
58+
throw StateError(
59+
'`AssetReader` must implement `AssetReaderState`: $this',
60+
);
61+
}
3962
}
63+
}
4064

41-
AssetPathProvider get assetPathProvider {
65+
/// Provides access to the state backing an [AssetWriter].
66+
extension AssetWriterStateExtension on RunnerAssetWriter {
67+
/// Returns a new instance with optionally updated [generatedAssetHider].
68+
RunnerAssetWriter copyWith({GeneratedAssetHider? generatedAssetHider}) {
4269
_requireIsAssetReaderState();
43-
return (this as AssetReaderState).assetPathProvider;
70+
return (this as AssetReaderState).copyWith(
71+
generatedAssetHider: generatedAssetHider,
72+
)
73+
as RunnerAssetWriter;
4474
}
4575

4676
/// Throws if `this` is not an [AssetReaderState].
@@ -55,21 +85,12 @@ extension AssetReaderStateExtension on AssetReader {
5585

5686
/// The state backing an [AssetReader].
5787
abstract interface class AssetReaderState {
58-
/// Returns a new instance with optionally updated [assetPathProvider] and/or [cache].
88+
/// Returns a new instance with optionally updated [cache] and/or [generatedAssetHider].
5989
AssetReaderWriter copyWith({
60-
AssetPathProvider? assetPathProvider,
6190
FilesystemCache? cache,
91+
GeneratedAssetHider? generatedAssetHider,
6292
});
6393

64-
/// The [Filesystem] that this reader reads from.
65-
///
66-
/// Warning: this access to the filesystem bypasses reader functionality
67-
/// such as read tracking, caching and visibility restriction.
68-
Filesystem get filesystem;
69-
70-
/// The [FilesystemCache] that this reader uses for caching.
71-
FilesystemCache get cache;
72-
7394
/// The [AssetFinder] associated with this reader.
7495
///
7596
/// All readers have an [AssetFinder], but the functionality it provides,
@@ -78,4 +99,16 @@ abstract interface class AssetReaderState {
7899

79100
/// The [AssetPathProvider] associated with this reader.
80101
AssetPathProvider get assetPathProvider;
102+
103+
/// The [GeneratedAssetHider] associated with this reader.
104+
GeneratedAssetHider get generatedAssetHider;
105+
106+
/// The [Filesystem] that this reader reads from.
107+
///
108+
/// Warning: this access to the filesystem bypasses reader functionality
109+
/// such as read tracking, caching and visibility restriction.
110+
Filesystem get filesystem;
111+
112+
/// The [FilesystemCache] that this reader uses for caching.
113+
FilesystemCache get cache;
81114
}

build/lib/src/state/reader_writer.dart

+12-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import 'asset_finder.dart';
1414
import 'asset_path_provider.dart';
1515
import 'filesystem.dart';
1616
import 'filesystem_cache.dart';
17+
import 'generated_asset_hider.dart';
1718
import 'reader_state.dart';
1819

1920
/// An [AssetReader] and [AssetWriter].
@@ -39,15 +40,21 @@ class DelegatingAssetReaderWriter
3940
@override
4041
AssetPathProvider get assetPathProvider => reader.assetPathProvider;
4142

43+
@override
44+
GeneratedAssetHider get generatedAssetHider => reader.generatedAssetHider;
45+
4246
@override
4347
FilesystemCache get cache => reader.cache;
4448

4549
@override
4650
AssetReaderWriter copyWith({
47-
AssetPathProvider? assetPathProvider,
4851
FilesystemCache? cache,
52+
GeneratedAssetHider? generatedAssetHider,
4953
}) => DelegatingAssetReaderWriter(
50-
reader: reader.copyWith(assetPathProvider: assetPathProvider, cache: cache),
54+
reader: reader.copyWith(
55+
cache: cache,
56+
generatedAssetHider: generatedAssetHider,
57+
),
5158
writer: writer,
5259
);
5360

@@ -80,4 +87,7 @@ class DelegatingAssetReaderWriter
8087
String contents, {
8188
Encoding encoding = utf8,
8289
}) => writer.writeAsString(id, contents);
90+
91+
// TODO(davidmorgan): fix interfaces/dependencies to improve this.
92+
Future delete(AssetId id) => throw UnimplementedError();
8393
}

build_runner_core/CHANGELOG.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
- Add internal `Filesystem` that backs `AssetReader` and `AssetWriter`
1313
implementations.
1414
- Refactor `CachingAssetReader` to `FilesystemCache`.
15-
- Refactor `BuildCacheReader` to `BuildCacheAssetPathProvider`.
15+
- Refactor `BuildCacheReader` to `GeneratedAssetHider`.
1616
- Refactor `FileBasedAssetReader` and `FileBasedAssetWriter` to `ReaderWriter`.
1717
- Move `BuildStepImpl` to `build_runner_core`, use `SingleStepReader` directly.
1818
- Remove `BuildCacheWriter`, functionality is handled by `AssetPathProvider`.

build_runner_core/lib/src/asset/build_cache.dart

-49
This file was deleted.

build_runner_core/lib/src/asset/reader_writer.dart

+19-11
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@ class ReaderWriter extends AssetReader
2424
/// Deletes are only allowed within this package.
2525
final String rootPackage;
2626

27+
@override
28+
final AssetFinder assetFinder;
2729
@override
2830
final AssetPathProvider assetPathProvider;
2931
@override
30-
final Filesystem filesystem;
32+
final GeneratedAssetHider generatedAssetHider;
3133
@override
32-
final AssetFinder assetFinder;
34+
final Filesystem filesystem;
3335
@override
3436
final FilesystemCache cache;
3537

@@ -45,6 +47,7 @@ class ReaderWriter extends AssetReader
4547
rootPackage: packageGraph.root.name,
4648
assetFinder: PackageGraphAssetFinder(packageGraph),
4749
assetPathProvider: packageGraph,
50+
generatedAssetHider: const NoopGeneratedAssetHider(),
4851
filesystem: IoFilesystem(),
4952
cache: const PassthroughFilesystemCache(),
5053
onDelete: null,
@@ -54,31 +57,36 @@ class ReaderWriter extends AssetReader
5457
required this.rootPackage,
5558
required this.assetFinder,
5659
required this.assetPathProvider,
60+
required this.generatedAssetHider,
5761
required this.filesystem,
5862
required this.cache,
5963
required this.onDelete,
6064
});
6165

6266
@override
6367
ReaderWriter copyWith({
64-
AssetPathProvider? assetPathProvider,
6568
FilesystemCache? cache,
69+
GeneratedAssetHider? generatedAssetHider,
6670
void Function(AssetId)? onDelete,
6771
}) => ReaderWriter.using(
6872
rootPackage: rootPackage,
6973
assetFinder: assetFinder,
70-
assetPathProvider: assetPathProvider ?? this.assetPathProvider,
74+
assetPathProvider: assetPathProvider,
75+
generatedAssetHider: generatedAssetHider ?? this.generatedAssetHider,
7176
filesystem: filesystem,
7277
cache: cache ?? this.cache,
7378
onDelete: onDelete ?? this.onDelete,
7479
);
7580

81+
String _pathFor(AssetId id) =>
82+
assetPathProvider.pathFor(generatedAssetHider.maybeHide(id, rootPackage));
83+
7684
@override
7785
Future<bool> canRead(AssetId id) {
7886
return cache.exists(
7987
id,
8088
ifAbsent: () async {
81-
final path = assetPathProvider.pathFor(id);
89+
final path = _pathFor(id);
8290
return filesystem.exists(path);
8391
},
8492
);
@@ -89,7 +97,7 @@ class ReaderWriter extends AssetReader
8997
return cache.readAsBytes(
9098
id,
9199
ifAbsent: () async {
92-
final path = assetPathProvider.pathFor(id);
100+
final path = _pathFor(id);
93101
if (!await filesystem.exists(path)) {
94102
throw AssetNotFoundException(id, path: path);
95103
}
@@ -104,7 +112,7 @@ class ReaderWriter extends AssetReader
104112
id,
105113
encoding: encoding,
106114
ifAbsent: () async {
107-
final path = assetPathProvider.pathFor(id);
115+
final path = _pathFor(id);
108116
if (!await filesystem.exists(path)) {
109117
throw AssetNotFoundException(id, path: path);
110118
}
@@ -121,7 +129,7 @@ class ReaderWriter extends AssetReader
121129

122130
@override
123131
Future<void> writeAsBytes(AssetId id, List<int> bytes) async {
124-
final path = assetPathProvider.pathFor(id);
132+
final path = _pathFor(id);
125133
await filesystem.writeAsBytes(path, bytes);
126134
}
127135

@@ -131,14 +139,14 @@ class ReaderWriter extends AssetReader
131139
String contents, {
132140
Encoding encoding = utf8,
133141
}) async {
134-
final path = assetPathProvider.pathFor(id);
142+
final path = _pathFor(id);
135143
await filesystem.writeAsString(path, contents, encoding: encoding);
136144
}
137145

138146
@override
139-
Future delete(AssetId id) async {
147+
Future<void> delete(AssetId id) async {
140148
onDelete?.call(id);
141-
final path = assetPathProvider.pathFor(id);
149+
final path = _pathFor(id);
142150
// Hidden generated files are moved by `assetPathProvider` under the root
143151
// package folder, and it's allowed to delete them. So for assets in a
144152
// different package, check if the path has mapped onto the generated output

0 commit comments

Comments
 (0)