diff --git a/build_runner/CHANGELOG.md b/build_runner/CHANGELOG.md index 7bab7e23e..759db4281 100644 --- a/build_runner/CHANGELOG.md +++ b/build_runner/CHANGELOG.md @@ -13,6 +13,7 @@ - Add `NodeType` to `AssetNode`, remove subtypes. Make mutations explicit. - Use `built_value` for `AssetNode` and related types. - Add details of what changed and what is built to `--verbose` logging. +- Compute outputs as needed instead of storing them in the asset graph. ## 2.4.15 diff --git a/build_runner/bin/graph_inspector.dart b/build_runner/bin/graph_inspector.dart index 55d0de571..0755c9cb2 100644 --- a/build_runner/bin/graph_inspector.dart +++ b/build_runner/bin/graph_inspector.dart @@ -118,6 +118,7 @@ class InspectNodeCommand extends Command { @override bool run() { + var computedOutputs = assetGraph.computeOutputs(); var argResults = this.argResults!; var stringUris = argResults.rest; if (stringUris.isEmpty) { @@ -157,12 +158,16 @@ class InspectNodeCommand extends Command { node.primaryOutputs.forEach(printAsset); description.writeln(' secondary outputs:'); - node.outputs.difference(node.primaryOutputs).forEach(printAsset); + (computedOutputs[node.id] ?? const {}) + .difference(node.primaryOutputs.asSet()) + .forEach(printAsset); if (node.type == NodeType.generated || node.type == NodeType.glob) { description.writeln(' inputs:'); assetGraph.allNodes - .where((n) => n.outputs.contains(node.id)) + .where( + (n) => (computedOutputs[n.id] ?? {}).contains(node.id), + ) .map((n) => n.id) .forEach(printAsset); } diff --git a/build_runner/lib/src/server/asset_graph_handler.dart b/build_runner/lib/src/server/asset_graph_handler.dart index 81923e814..9a0b513fd 100644 --- a/build_runner/lib/src/server/asset_graph_handler.dart +++ b/build_runner/lib/src/server/asset_graph_handler.dart @@ -115,7 +115,8 @@ class AssetGraphHandler { {'id': '${node.id}', 'label': '${node.id}'}, ]; var edges = >[]; - for (final output in node.outputs) { + var computedOutputs = _assetGraph.computeOutputs(); + for (final output in (computedOutputs[node.id] ?? {})) { if (filterGlob != null && !filterGlob.matches(output.toString())) { continue; } diff --git a/build_runner/test/generate/watch_test.dart b/build_runner/test/generate/watch_test.dart index 43f96da30..481c4a90b 100644 --- a/build_runner/test/generate/watch_test.dart +++ b/build_runner/test/generate/watch_test.dart @@ -382,9 +382,6 @@ void main() { inputs: [makeAssetId('a|web/b.txt')], isHidden: false, ); - builderOptionsNode = builderOptionsNode.rebuild( - (b) => b..outputs.add(bCopyNode.id), - ); expectedGraph ..add(bCopyNode) ..add( @@ -407,9 +404,6 @@ void main() { inputs: [makeAssetId('a|web/c.txt')], isHidden: false, ); - builderOptionsNode = builderOptionsNode.rebuild( - (b) => b..outputs.add(cCopyNode.id), - ); expectedGraph ..add(cCopyNode) ..add( diff --git a/build_runner_core/CHANGELOG.md b/build_runner_core/CHANGELOG.md index f721bda37..0290da06c 100644 --- a/build_runner_core/CHANGELOG.md +++ b/build_runner_core/CHANGELOG.md @@ -29,6 +29,7 @@ - Use `LibraryCycleGraphLoader` to load transitive deps for analysis. - Track post process builder outputs separately from the main graph Instead of in `postProcessAnchor` nodes. +- Compute outputs as needed instead of storing them in the asset graph. ## 8.0.0 diff --git a/build_runner_core/lib/src/asset_graph/graph.dart b/build_runner_core/lib/src/asset_graph/graph.dart index bc4bf8e22..26ef089a7 100644 --- a/build_runner_core/lib/src/asset_graph/graph.dart +++ b/build_runner_core/lib/src/asset_graph/graph.dart @@ -49,6 +49,10 @@ class AssetGraph implements GeneratedAssetHider { final BuiltMap packageLanguageVersions; + /// The result of [computeOutputs] for reuse, or `null` if outputs have not + /// been computed. + Map>? _outputs; + /// All post process build steps outputs, indexed by package then /// [PostProcessBuildStepId]. /// @@ -129,6 +133,11 @@ class AssetGraph implements GeneratedAssetHider { if (node == null) throw StateError('Missing node: $id'); final updatedNode = node.rebuild(updates); _nodesByPackage[id.package]![id.path] = updatedNode; + + if (node.inputs != updatedNode.inputs) { + _outputs = null; + } + return updatedNode; } @@ -145,6 +154,11 @@ class AssetGraph implements GeneratedAssetHider { if (node == null) return null; final updatedNode = node.rebuild(updates); _nodesByPackage[id.package]![id.path] = updatedNode; + + if (node.inputs != updatedNode.inputs) { + _outputs = null; + } + return updatedNode; } @@ -162,7 +176,6 @@ class AssetGraph implements GeneratedAssetHider { // primary outputs. We only want to remove this node. _nodesByPackage[existing.id.package]!.remove(existing.id.path); node = node.rebuild((b) { - b.outputs.addAll(existing.outputs); b.primaryOutputs.addAll(existing.primaryOutputs); }); } else { @@ -173,6 +186,10 @@ class AssetGraph implements GeneratedAssetHider { } } _nodesByPackage.putIfAbsent(node.id.package, () => {})[node.id.path] = node; + if (node.inputs?.isNotEmpty ?? false) { + _outputs = null; + } + return node; } @@ -261,7 +278,8 @@ class AssetGraph implements GeneratedAssetHider { for (var output in node.primaryOutputs.toList()) { _removeRecursive(output, removedIds: removedIds); } - for (var output in node.outputs) { + final outputs = computeOutputs(); + for (var output in (outputs[node.id] ?? const {})) { updateNodeIfPresent(output, (nodeBuilder) { if (nodeBuilder.type == NodeType.generated) { nodeBuilder.generatedNodeState.inputs.remove(id); @@ -277,23 +295,14 @@ class AssetGraph implements GeneratedAssetHider { for (var input in node.generatedNodeState!.inputs) { // We may have already removed this node entirely. updateNodeIfPresent(input, (nodeBuilder) { - nodeBuilder - ..outputs.remove(id) - ..primaryOutputs.remove(id); + nodeBuilder.primaryOutputs.remove(id); }); } - updateNode(node.generatedNodeConfiguration!.builderOptionsId, ( - nodeBuilder, - ) { - nodeBuilder.outputs.remove(id); - }); } else if (node.type == NodeType.glob) { for (var input in node.globNodeState!.inputs) { // We may have already removed this node entirely. updateNodeIfPresent(input, (nodeBuilder) { - nodeBuilder - ..outputs.remove(id) - ..primaryOutputs.remove(id); + nodeBuilder.primaryOutputs.remove(id); }); } } @@ -311,6 +320,34 @@ class AssetGraph implements GeneratedAssetHider { return removedIds; } + /// Computes node outputs: the inverse of the graph described by the `inputs` + /// fields on glob and generated nodes. + /// + /// The result is cached until any node is updated with different `inputs` or + /// [updateAndInvalidate] is called. + Map> computeOutputs() { + if (_outputs != null) return _outputs!; + final result = >{}; + for (final node in allNodes) { + if (node.type == NodeType.generated) { + for (final input in node.generatedNodeState!.inputs) { + result.putIfAbsent(input, () => {}).add(node.id); + } + result + .putIfAbsent( + node.generatedNodeConfiguration!.builderOptionsId, + () => {}, + ) + .add(node.id); + } else if (node.type == NodeType.glob) { + for (final input in node.globNodeState!.inputs) { + result.putIfAbsent(input, () => {}).add(node.id); + } + } + } + return _outputs = result; + } + /// All nodes in the graph, whether source files or generated outputs. Iterable get allNodes => _nodesByPackage.values.expand((pkdIds) => pkdIds.values); @@ -408,8 +445,7 @@ class AssetGraph implements GeneratedAssetHider { .where( (node) => node.isTrackedInput && - (node.outputs.isNotEmpty || - node.primaryOutputs.isNotEmpty || + (node.primaryOutputs.isNotEmpty || node.lastKnownDigest != null), ) .map((node) => node.id), @@ -458,6 +494,7 @@ class AssetGraph implements GeneratedAssetHider { // Transitively invalidates all assets. This needs to happen after the // structure of the graph has been updated. var invalidatedIds = {}; + final computedOutputs = computeOutputs(); void invalidateNodeAndDeps(AssetId startNodeId) { if (!invalidatedIds.add(startNodeId)) return; @@ -484,7 +521,8 @@ class AssetGraph implements GeneratedAssetHider { }); if (invalidatedNode != null) { - for (final id in invalidatedNode.outputs) { + for (final id + in (computedOutputs[invalidatedNode.id] ?? const {})) { if (invalidatedIds.add(id)) { nodesToInvalidate.add(id); } @@ -534,6 +572,7 @@ class AssetGraph implements GeneratedAssetHider { } } + _outputs = null; return invalidatedIds; } @@ -681,12 +720,14 @@ class AssetGraph implements GeneratedAssetHider { throw ArgumentError('Expected node of type NodeType.builderOptionsNode'); } var removed = {}; + Map>? computedOutputsBeforeRemoves; for (var output in outputs) { AssetNode? existing; // When any outputs aren't hidden we can pick up old generated outputs as // regular `AssetNode`s, we need to delete them and all their primary // outputs, and replace them with a `GeneratedAssetNode`. if (contains(output)) { + computedOutputsBeforeRemoves = computeOutputs(); existing = get(output)!; if (existing.type == NodeType.generated) { final existingConfiguration = existing.generatedNodeConfiguration!; @@ -712,13 +753,9 @@ class AssetGraph implements GeneratedAssetHider { isHidden: isHidden, ); if (existing != null) { - newNode = newNode.rebuild((b) => b..outputs.addAll(existing!.outputs)); // Ensure we set up the reverse link for NodeWithInput nodes. - _addInput(existing.outputs, output); + _addInput(computedOutputsBeforeRemoves![output] ?? {}, output); } - updateNode(builderOptionsNode.id, (nodeBuilder) { - nodeBuilder.outputs.add(output); - }); _add(newNode); } return removed; diff --git a/build_runner_core/lib/src/asset_graph/node.dart b/build_runner_core/lib/src/asset_graph/node.dart index 615183fc0..c2a8412eb 100644 --- a/build_runner_core/lib/src/asset_graph/node.dart +++ b/build_runner_core/lib/src/asset_graph/node.dart @@ -57,10 +57,6 @@ abstract class AssetNode implements Built { /// when run on this asset. BuiltSet get primaryOutputs; - /// The [AssetId]s of all generated assets which are output by a [Builder] - /// which reads this asset. - BuiltSet get outputs; - /// The [Digest] for this node in its last known state. /// /// May be `null` if this asset has no outputs, or if it doesn't actually @@ -96,7 +92,6 @@ abstract class AssetNode implements Built { bool get changesRequireRebuild => type == NodeType.internal || type == NodeType.glob || - outputs.isNotEmpty || lastKnownDigest != null; factory AssetNode([void Function(AssetNodeBuilder) updates]) = _$AssetNode; @@ -124,7 +119,6 @@ abstract class AssetNode implements Built { b.id = id; b.type = NodeType.source; b.primaryOutputs.replace(primaryOutputs ?? {}); - b.outputs.replace(outputs ?? {}); b.lastKnownDigest = lastKnownDigest; }); @@ -239,6 +233,19 @@ abstract class AssetNode implements Built { globNodeState != null, ); } + + /// The generated node inputs, or the glob node inputs, or `null` if the node + /// is not of one of those two types. + BuiltSet? get inputs { + switch (type) { + case NodeType.generated: + return generatedNodeState!.inputs; + case NodeType.glob: + return globNodeState!.inputs; + default: + return null; + } + } } /// Additional configuration for an [AssetNode.generated]. diff --git a/build_runner_core/lib/src/asset_graph/node.g.dart b/build_runner_core/lib/src/asset_graph/node.g.dart index e9a0ac844..5cb6313c1 100644 --- a/build_runner_core/lib/src/asset_graph/node.g.dart +++ b/build_runner_core/lib/src/asset_graph/node.g.dart @@ -133,13 +133,6 @@ class _$AssetNodeSerializer implements StructuredSerializer { const FullType(AssetId), ]), ), - 'outputs', - serializers.serialize( - object.outputs, - specifiedType: const FullType(BuiltSet, const [ - const FullType(AssetId), - ]), - ), 'deletedBy', serializers.serialize( object.deletedBy, @@ -281,17 +274,6 @@ class _$AssetNodeSerializer implements StructuredSerializer { as BuiltSet, ); break; - case 'outputs': - result.outputs.replace( - serializers.deserialize( - value, - specifiedType: const FullType(BuiltSet, const [ - const FullType(AssetId), - ]), - )! - as BuiltSet, - ); - break; case 'lastKnownDigest': result.lastKnownDigest = serializers.deserialize( @@ -702,8 +684,6 @@ class _$AssetNode extends AssetNode { @override final BuiltSet primaryOutputs; @override - final BuiltSet outputs; - @override final Digest? lastKnownDigest; @override final BuiltSet deletedBy; @@ -719,7 +699,6 @@ class _$AssetNode extends AssetNode { this.globNodeConfiguration, this.globNodeState, required this.primaryOutputs, - required this.outputs, this.lastKnownDigest, required this.deletedBy, }) : super._() { @@ -730,7 +709,6 @@ class _$AssetNode extends AssetNode { r'AssetNode', 'primaryOutputs', ); - BuiltValueNullFieldError.checkNotNull(outputs, r'AssetNode', 'outputs'); BuiltValueNullFieldError.checkNotNull(deletedBy, r'AssetNode', 'deletedBy'); } @@ -752,7 +730,6 @@ class _$AssetNode extends AssetNode { globNodeConfiguration == other.globNodeConfiguration && globNodeState == other.globNodeState && primaryOutputs == other.primaryOutputs && - outputs == other.outputs && lastKnownDigest == other.lastKnownDigest && deletedBy == other.deletedBy; } @@ -767,7 +744,6 @@ class _$AssetNode extends AssetNode { _$hash = $jc(_$hash, globNodeConfiguration.hashCode); _$hash = $jc(_$hash, globNodeState.hashCode); _$hash = $jc(_$hash, primaryOutputs.hashCode); - _$hash = $jc(_$hash, outputs.hashCode); _$hash = $jc(_$hash, lastKnownDigest.hashCode); _$hash = $jc(_$hash, deletedBy.hashCode); _$hash = $jf(_$hash); @@ -784,7 +760,6 @@ class _$AssetNode extends AssetNode { ..add('globNodeConfiguration', globNodeConfiguration) ..add('globNodeState', globNodeState) ..add('primaryOutputs', primaryOutputs) - ..add('outputs', outputs) ..add('lastKnownDigest', lastKnownDigest) ..add('deletedBy', deletedBy)) .toString(); @@ -835,11 +810,6 @@ class AssetNodeBuilder implements Builder { set primaryOutputs(SetBuilder? primaryOutputs) => _$this._primaryOutputs = primaryOutputs; - SetBuilder? _outputs; - SetBuilder get outputs => - _$this._outputs ??= new SetBuilder(); - set outputs(SetBuilder? outputs) => _$this._outputs = outputs; - Digest? _lastKnownDigest; Digest? get lastKnownDigest => _$this._lastKnownDigest; set lastKnownDigest(Digest? lastKnownDigest) => @@ -863,7 +833,6 @@ class AssetNodeBuilder implements Builder { _globNodeConfiguration = $v.globNodeConfiguration?.toBuilder(); _globNodeState = $v.globNodeState?.toBuilder(); _primaryOutputs = $v.primaryOutputs.toBuilder(); - _outputs = $v.outputs.toBuilder(); _lastKnownDigest = $v.lastKnownDigest; _deletedBy = $v.deletedBy.toBuilder(); _$v = null; @@ -902,7 +871,6 @@ class AssetNodeBuilder implements Builder { globNodeConfiguration: _globNodeConfiguration?.build(), globNodeState: _globNodeState?.build(), primaryOutputs: primaryOutputs.build(), - outputs: outputs.build(), lastKnownDigest: lastKnownDigest, deletedBy: deletedBy.build(), ); @@ -919,8 +887,6 @@ class AssetNodeBuilder implements Builder { _globNodeState?.build(); _$failedField = 'primaryOutputs'; primaryOutputs.build(); - _$failedField = 'outputs'; - outputs.build(); _$failedField = 'deletedBy'; deletedBy.build(); diff --git a/build_runner_core/lib/src/asset_graph/optional_output_tracker.dart b/build_runner_core/lib/src/asset_graph/optional_output_tracker.dart index 4f9946221..cf57bbb5e 100644 --- a/build_runner_core/lib/src/asset_graph/optional_output_tracker.dart +++ b/build_runner_core/lib/src/asset_graph/optional_output_tracker.dart @@ -73,7 +73,9 @@ class OptionalOutputTracker { return _checkedOutputs.putIfAbsent( output, () => - node.outputs.any((o) => isRequired(o, currentlyChecking)) || + (_assetGraph.computeOutputs()[node.id] ?? {}).any( + (o) => isRequired(o, currentlyChecking), + ) || _assetGraph .outputsForPhase(output.package, nodeConfiguration.phaseNumber) .where( diff --git a/build_runner_core/lib/src/generate/build.dart b/build_runner_core/lib/src/generate/build.dart index 6d2a3c15a..d9744455f 100644 --- a/build_runner_core/lib/src/generate/build.dart +++ b/build_runner_core/lib/src/generate/build.dart @@ -936,13 +936,6 @@ class Build { } } - // Mark the glob node as an output of all the inputs. - for (var id in generatedFileInputs.followedBy(otherInputs)) { - assetGraph.updateNode(id, (nodeBuilder) { - nodeBuilder.outputs.add(globId); - }); - } - // Request to build the matching generated files. for (final id in generatedFileInputs) { await _buildAsset(id); @@ -1006,19 +999,20 @@ class Build { var wasOutput = readerWriter.assetsWritten.contains(output); var digest = wasOutput ? await this.readerWriter.digest(output) : null; - _removeOldInputs(output, usedInputs); - _addNewInputs(output, usedInputs); assetGraph.updateNode(output, (nodeBuilder) { if (nodeBuilder.lastKnownDigest != digest) { changedOutputs.add(output); } nodeBuilder.generatedNodeState + ..inputs.replace(usedInputs) ..pendingBuildAction = PendingBuildAction.none ..wasOutput = wasOutput ..isFailure = isFailure; nodeBuilder.lastKnownDigest = digest; }); + assetGraph.updateNode(output, (nodeBuilder) {}); + if (isFailure) { final node = assetGraph.get(output)!; await failureReporter.markReported(actionDescription, node, errors); @@ -1040,10 +1034,7 @@ class Build { needsMarkAsFailure.addAll(assetGraph.get(output)!.primaryOutputs); // Make sure output invalidation follows primary outputs for builds - // that won't run - assetGraph.updateNode(node.id, (nodeBuilder) { - nodeBuilder.outputs.add(output); - }); + // that won't run. assetGraph.updateNode(output, (nodeBuilder) { nodeBuilder.generatedNodeState.inputs.add(node.id); }); @@ -1055,38 +1046,6 @@ class Build { } } - /// Removes old inputs from node with [id] based on [updatedInputs], and - /// cleans up all the old edges. - void _removeOldInputs(AssetId id, Set updatedInputs) { - final node = assetGraph.get(id)!; - final nodeState = node.generatedNodeState!; - var removedInputs = nodeState.inputs.asSet().difference(updatedInputs); - assetGraph.updateNode(node.id, (nodeBuilder) { - nodeBuilder.generatedNodeState.inputs.removeAll(removedInputs); - }); - for (var input in removedInputs) { - assetGraph.updateNode(input, (nodeBuilder) { - nodeBuilder.outputs.remove(node.id); - }); - } - } - - /// Adds new inputs to node with [id] based on [updatedInputs], and adds the - /// appropriate edges. - void _addNewInputs(AssetId id, Set updatedInputs) { - final node = assetGraph.get(id)!; - final nodeState = node.generatedNodeState!; - var newInputs = updatedInputs.difference(nodeState.inputs.asSet()); - assetGraph.updateNode(node.id, (nodeBuilder) { - nodeBuilder.generatedNodeState.inputs.addAll(newInputs); - }); - for (var input in newInputs) { - assetGraph.updateNode(input, (nodeBuilder) { - nodeBuilder.outputs.add(node.id); - }); - } - } - Future _delete(AssetId id) => deleteWriter.delete(id); } diff --git a/build_runner_core/test/asset_graph/graph_test.dart b/build_runner_core/test/asset_graph/graph_test.dart index a7f2ae316..ada7b95dd 100644 --- a/build_runner_core/test/asset_graph/graph_test.dart +++ b/build_runner_core/test/asset_graph/graph_test.dart @@ -106,7 +106,6 @@ void main() { ..inputs.add(node.id) ..results.add(node.id), ); - node = node.rebuild((b) => b..outputs.add(globNode.id)); var phaseNum = n; final builderOptionsNode = AssetNode.builderOptions( makeAssetId(), @@ -136,27 +135,14 @@ void main() { builderOptionsId: builderOptionsNode.id, isHidden: g % 3 == 0, ); - node = node.rebuild( - (b) => - b - ..outputs.add(generatedNode.id) - ..primaryOutputs.add(generatedNode.id), - ); - globNode = globNode.rebuild( - (b) => b..outputs.add(generatedNode.id), - ); - builderOptionsNode = builderOptionsNode.rebuild( - (b) => b..outputs.add(generatedNode.id), - ); + node = node.rebuild((b) => b..primaryOutputs.add(generatedNode.id)); if (g.isEven) { node = node.rebuild( (b) => b..deletedBy.add(postProcessBuildStep), ); } - var syntheticNode = AssetNode.missingSource( - makeAssetId(), - ).rebuild((b) => b..outputs.add(generatedNode.id)); + var syntheticNode = AssetNode.missingSource(makeAssetId()); generatedNode = generatedNode.rebuild( (b) => b.generatedNodeState.inputs.addAll([ @@ -271,7 +257,7 @@ void main() { }); var node = graph.get(primaryInputId)!; expect(node.primaryOutputs, [primaryOutputId]); - expect(node.outputs, isEmpty); + expect(graph.computeOutputs()[node.id] ?? {}, isEmpty); expect( node.lastKnownDigest, isNotNull, @@ -302,12 +288,18 @@ void main() { var builderOptionsNode = graph.get(builderOptionsId)!; expect(builderOptionsNode.type, NodeType.builderOptions); - expect(builderOptionsNode.outputs, unorderedEquals([primaryOutputId])); + expect( + graph.computeOutputs()[builderOptionsNode.id]!, + unorderedEquals([primaryOutputId]), + ); var postBuilderOptionsNode = graph.get(postBuilderOptionsId)!; expect(postBuilderOptionsNode.type, NodeType.builderOptions); expect(postBuilderOptionsNode, isNotNull); - expect(postBuilderOptionsNode.outputs, isEmpty); + expect( + graph.computeOutputs()[postBuilderOptionsNode.id] ?? {}, + isEmpty, + ); expect(graph.postProcessBuildStepIds(package: 'foo'), { expectedBuildStepId, }); @@ -361,9 +353,6 @@ void main() { ..pendingBuildAction = PendingBuildAction.none ..inputs.add(primaryInputId); }); - graph.updateNode(primaryInputId, (nodeBuilder) { - nodeBuilder.outputs.add(primaryOutputId); - }); await graph.updateAndInvalidate( buildPhases, changes, @@ -438,9 +427,7 @@ void main() { 'removing nodes deletes primary outputs and secondary edges', () async { var secondaryId = makeAssetId('foo|secondary.txt'); - var secondaryNode = AssetNode.source( - secondaryId, - ).rebuild((b) => b..outputs.add(primaryOutputId)); + var secondaryNode = AssetNode.source(secondaryId); graph.updateNode(primaryOutputId, (nodeBuilder) { nodeBuilder.generatedNodeState.inputs.add(secondaryNode.id); @@ -461,7 +448,7 @@ void main() { expect(graph.contains(primaryInputId), isFalse); expect(graph.contains(primaryOutputId), isFalse); expect( - graph.get(secondaryId)!.outputs, + graph.computeOutputs()[secondaryId] ?? const {}, isNot(contains(primaryOutputId)), ); }, @@ -485,7 +472,6 @@ void main() { ..inputs.add(globNode.id); }); - globNode = globNode.rebuild((b) => b..outputs.add(primaryOutputId)); graph.add(globNode); var coolAssetId = AssetId('foo', 'lib/really.cool'); @@ -553,9 +539,6 @@ void main() { ..inputs.add(coolAssetId) ..results.add(coolAssetId); }); - graph.updateNode(coolAssetId, (nodeBuilder) { - nodeBuilder.outputs.add(globNode.id); - }); await checkChangeType(ChangeType.MODIFY); expect(globNode.globNodeState!.inputs, contains(coolAssetId)); @@ -714,16 +697,11 @@ void main() { ); // Pretend a build happened - graph.add( - AssetNode.missingSource( - nodeToRead, - ).rebuild((b) => b..outputs.add(outputReadingNode)), - ); + graph.add(AssetNode.missingSource(nodeToRead)); graph.updateNode(outputReadingNode, (nodeBuilder) { nodeBuilder.generatedNodeState ..pendingBuildAction = PendingBuildAction.none ..inputs.add(nodeToRead); - nodeBuilder.outputs.add(lastPrimaryOutputNode); }); graph.updateNode(lastPrimaryOutputNode, (nodeBuilder) { nodeBuilder.generatedNodeState @@ -772,21 +750,14 @@ void main() { ); // Pretend a build happened - graph.add( - AssetNode.missingSource( - toBeGeneratedDart, - ).rebuild((b) => b..outputs.add(generatedPart)), - ); + graph.add(AssetNode.missingSource(toBeGeneratedDart)); graph.updateNode(generatedDart, (nodeBuilder) { nodeBuilder.generatedNodeState ..pendingBuildAction = PendingBuildAction.none ..inputs.addAll([generatedPart, toBeGeneratedDart]); }); - graph.updateNode(source, (nodeBuilder) { - expect(nodeBuilder.type, NodeType.source); - nodeBuilder.outputs.add(generatedPart); - }); + expect(graph.get(source)!.type, NodeType.source); await graph.updateAndInvalidate( buildPhases, @@ -802,7 +773,7 @@ void main() { // The generated part file should not exist in outputs of the new // generated dart file expect( - graph.get(toBeGeneratedDart)!.outputs, + graph.computeOutputs()[toBeGeneratedDart] ?? {}, isNot(contains(generatedPart)), ); }); diff --git a/build_runner_core/test/generate/build_definition_test.dart b/build_runner_core/test/generate/build_definition_test.dart index 5adae3a44..71b0578bd 100644 --- a/build_runner_core/test/generate/build_definition_test.dart +++ b/build_runner_core/test/generate/build_definition_test.dart @@ -228,9 +228,6 @@ targets: ..pendingBuildAction = PendingBuildAction.none ..inputs.add(aTxt); }); - originalAssetGraph.updateNode(aTxt, (nodeBuilder) { - nodeBuilder.outputs.add(aTxtCopy); - }); await createFile(assetGraphPath, originalAssetGraph.serialize()); await modifyFile(p.join('lib', 'a.txt'), 'b'); diff --git a/build_runner_core/test/generate/build_test.dart b/build_runner_core/test/generate/build_test.dart index 4eb959667..53f04b917 100644 --- a/build_runner_core/test/generate/build_test.dart +++ b/build_runner_core/test/generate/build_test.dart @@ -1287,14 +1287,8 @@ void main() { inputs: [makeAssetId('a|web/a.txt')], isHidden: false, ); - builderOptionsNode = builderOptionsNode.rebuild( - (b) => b..outputs.add(aCopyNode.id), - ); aSourceNode = aSourceNode.rebuild( - (b) => - b - ..outputs.add(aCopyNode.id) - ..primaryOutputs.add(aCopyNode.id), + (b) => b..primaryOutputs.add(aCopyNode.id), ); var bCopyId = makeAssetId('a|lib/b.txt.copy'); //; @@ -1310,14 +1304,8 @@ void main() { inputs: [makeAssetId('a|lib/b.txt')], isHidden: false, ); - builderOptionsNode = builderOptionsNode.rebuild( - (b) => b..outputs.add(bCopyNode.id), - ); bSourceNode = bSourceNode.rebuild( - (b) => - b - ..outputs.add(bCopyNode.id) - ..primaryOutputs.add(bCopyNode.id), + (b) => b..primaryOutputs.add(bCopyNode.id), ); // Post build generates asset nodes and supporting nodes @@ -1350,7 +1338,6 @@ void main() { ); // Note we don't expect this node to get added to the builder options node // outputs. - aSourceNode = aSourceNode.rebuild((b) => b..outputs.add(aPostCopyNode.id)); aSourceNode = aSourceNode.rebuild( (b) => b..primaryOutputs.add(aPostCopyNode.id), ); @@ -1369,7 +1356,6 @@ void main() { ); // Note we don't expect this node to get added to the builder options node // outputs. - bSourceNode = bSourceNode.rebuild((b) => b..outputs.add(bPostCopyNode.id)); bSourceNode = bSourceNode.rebuild( (b) => b..primaryOutputs.add(bPostCopyNode.id), ); @@ -1834,9 +1820,10 @@ void main() { outputNode.generatedNodeState!.inputs, unorderedEquals([fileANode.id, fileCNode.id]), ); - expect(fileANode.outputs, contains(outputNode.id)); - expect(fileBNode.outputs, isEmpty); - expect(fileCNode.outputs, unorderedEquals([outputNode.id])); + final computedOutputs = graph.computeOutputs(); + expect(computedOutputs[fileANode.id]!, contains(outputNode.id)); + expect(computedOutputs[fileBNode.id] ?? const {}, isEmpty); + expect(computedOutputs[fileCNode.id]!, unorderedEquals([outputNode.id])); }); test('Ouputs aren\'t rebuilt if their inputs didn\'t change', () async {