Provide specific field to accept depfiles in target class (#44481)

* add depfile slot to Target class

* Update source.dart

* Update source.dart
diff --git a/packages/flutter_tools/lib/src/build_system/build_system.dart b/packages/flutter_tools/lib/src/build_system/build_system.dart
index c81a43c..cb0dc84 100644
--- a/packages/flutter_tools/lib/src/build_system/build_system.dart
+++ b/packages/flutter_tools/lib/src/build_system/build_system.dart
@@ -123,6 +123,9 @@
   /// The output [Source]s which we attempt to verify are correctly produced.
   List<Source> get outputs;
 
+  /// A list of zero or more depfiles, located directly under {BUILD_DIR}.
+  List<String> get depfiles => const <String>[];
+
   /// The action which performs this build step.
   Future<void> build(Environment environment);
 
@@ -177,7 +180,7 @@
   /// Resolve the set of input patterns and functions into a concrete list of
   /// files.
   ResolvedFiles resolveInputs(Environment environment) {
-    return _resolveConfiguration(inputs, environment, implicit: true, inputs: true);
+    return _resolveConfiguration(inputs, depfiles, environment, implicit: true, inputs: true);
   }
 
   /// Find the current set of declared outputs, including wildcard directories.
@@ -185,7 +188,7 @@
   /// The [implicit] flag controls whether it is safe to evaluate [Source]s
   /// which uses functions, behaviors, or patterns.
   ResolvedFiles resolveOutputs(Environment environment) {
-    return _resolveConfiguration(outputs, environment, inputs: false);
+    return _resolveConfiguration(outputs, depfiles, environment, inputs: false);
   }
 
   /// Performs a fold across this target and its dependencies.
@@ -222,13 +225,14 @@
     return environment.buildDir.childFile(fileName);
   }
 
-  static ResolvedFiles _resolveConfiguration(List<Source> config, Environment environment, {
-    bool implicit = true, bool inputs = true,
+  static ResolvedFiles _resolveConfiguration(List<Source> config,
+    List<String> depfiles, Environment environment, { bool implicit = true, bool inputs = true,
   }) {
     final SourceVisitor collector = SourceVisitor(environment, inputs);
     for (Source source in config) {
       source.accept(collector);
     }
+    depfiles.forEach(collector.visitDepfile);
     return collector;
   }
 }
diff --git a/packages/flutter_tools/lib/src/build_system/source.dart b/packages/flutter_tools/lib/src/build_system/source.dart
index 3dbb926..43c13cb 100644
--- a/packages/flutter_tools/lib/src/build_system/source.dart
+++ b/packages/flutter_tools/lib/src/build_system/source.dart
@@ -190,16 +190,6 @@
   /// If [artifact] points to a directory then all child files are included.
   const factory Source.artifact(Artifact artifact, {TargetPlatform platform, BuildMode mode}) = _ArtifactSource;
 
-  /// The source is provided by a depfile generated at runtime.
-  ///
-  /// The `name` is of the file, and is expected to be output relative to the
-  /// build directory.
-  ///
-  /// Before the first build, the depfile is expected to be missing. Its
-  /// absence is interpreted as the build needing to run. Afterwards, both
-  /// input and output file hashes are updated.
-  const factory Source.depfile(String name) = _DepfileSource;
-
   /// Visit the particular source type.
   void accept(SourceVisitor visitor);
 
@@ -239,15 +229,3 @@
   @override
   bool get implicit => false;
 }
-
-class _DepfileSource implements Source {
-  const _DepfileSource(this.name);
-
-  final String name;
-
-  @override
-  void accept(SourceVisitor visitor) => visitor.visitDepfile(name);
-
-  @override
-  bool get implicit => false;
-}
diff --git a/packages/flutter_tools/lib/src/build_system/targets/android.dart b/packages/flutter_tools/lib/src/build_system/targets/android.dart
index 98336d4..eb7a8c5 100644
--- a/packages/flutter_tools/lib/src/build_system/targets/android.dart
+++ b/packages/flutter_tools/lib/src/build_system/targets/android.dart
@@ -24,12 +24,14 @@
   @override
   List<Source> get inputs => const <Source>[
     Source.pattern('{BUILD_DIR}/app.dill'),
-    Source.depfile('flutter_assets.d'),
   ];
 
   @override
-  List<Source> get outputs => const <Source>[
-    Source.depfile('flutter_assets.d'),
+  List<Source> get outputs => const <Source>[];
+
+  @override
+  List<String> get depfiles => const <String>[
+    'flutter_assets.d',
   ];
 
   @override
diff --git a/packages/flutter_tools/lib/src/build_system/targets/assets.dart b/packages/flutter_tools/lib/src/build_system/targets/assets.dart
index b67765a..3872071 100644
--- a/packages/flutter_tools/lib/src/build_system/targets/assets.dart
+++ b/packages/flutter_tools/lib/src/build_system/targets/assets.dart
@@ -64,12 +64,14 @@
   @override
   List<Source> get inputs => const <Source>[
     Source.pattern('{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/assets.dart'),
-    Source.depfile('flutter_assets.d'),
   ];
 
   @override
-  List<Source> get outputs => const <Source>[
-    Source.depfile('flutter_assets.d'),
+  List<Source> get outputs => const <Source>[];
+
+  @override
+  List<String> get depfiles => const <String>[
+    'flutter_assets.d'
   ];
 
   @override
diff --git a/packages/flutter_tools/lib/src/build_system/targets/dart.dart b/packages/flutter_tools/lib/src/build_system/targets/dart.dart
index aa0d204..60165ad 100644
--- a/packages/flutter_tools/lib/src/build_system/targets/dart.dart
+++ b/packages/flutter_tools/lib/src/build_system/targets/dart.dart
@@ -75,7 +75,6 @@
     Source.artifact(Artifact.vmSnapshotData, mode: BuildMode.debug),
     Source.artifact(Artifact.isolateSnapshotData, mode: BuildMode.debug),
     Source.pattern('{BUILD_DIR}/app.dill'),
-    Source.depfile('flutter_assets.d'),
   ];
 
   @override
@@ -83,7 +82,11 @@
     Source.pattern('{OUTPUT_DIR}/vm_snapshot_data'),
     Source.pattern('{OUTPUT_DIR}/isolate_snapshot_data'),
     Source.pattern('{OUTPUT_DIR}/kernel_blob.bin'),
-    Source.depfile('flutter_assets.d'),
+  ];
+
+  @override
+  List<String> get depfiles => <String>[
+    'flutter_assets.d'
   ];
 
   @override
@@ -123,13 +126,14 @@
   String get name => 'release_flutter_bundle';
 
   @override
-  List<Source> get inputs => const <Source>[
-    Source.depfile('flutter_assets.d'),
-  ];
+  List<Source> get inputs => const <Source>[];
 
   @override
-  List<Source> get outputs => const <Source>[
-    Source.depfile('flutter_assets.d'),
+  List<Source> get outputs => const <Source>[];
+
+  @override
+  List<String> get depfiles => const <String>[
+    'flutter_assets.d',
   ];
 
   @override
@@ -151,12 +155,14 @@
     Source.artifact(Artifact.platformKernelDill),
     Source.artifact(Artifact.engineDartBinary),
     Source.artifact(Artifact.frontendServerSnapshotForEngineDartSdk),
-    Source.depfile('kernel_snapshot.d'),
   ];
 
   @override
-  List<Source> get outputs => const <Source>[
-    Source.depfile('kernel_snapshot.d'),
+  List<Source> get outputs => const <Source>[];
+
+  @override
+  List<String> get depfiles => <String>[
+    'kernel_snapshot.d',
   ];
 
   @override
diff --git a/packages/flutter_tools/lib/src/build_system/targets/linux.dart b/packages/flutter_tools/lib/src/build_system/targets/linux.dart
index 28be773..08a2c0d 100644
--- a/packages/flutter_tools/lib/src/build_system/targets/linux.dart
+++ b/packages/flutter_tools/lib/src/build_system/targets/linux.dart
@@ -33,12 +33,14 @@
   @override
   List<Source> get inputs => const <Source>[
     Source.pattern('{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/linux.dart'),
-    Source.depfile('linux_engine_sources.d'),
   ];
 
   @override
-  List<Source> get outputs => const <Source>[
-    Source.depfile('linux_engine_sources.d'),
+  List<Source> get outputs => const <Source>[];
+
+  @override
+  List<String> get depfiles => <String>[
+    'linux_engine_sources.d'
   ];
 
   @override
@@ -116,17 +118,20 @@
   List<Source> get inputs => const <Source>[
     Source.pattern('{BUILD_DIR}/app.dill'),
     Source.pattern('{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/linux.dart'),
-    Source.depfile('flutter_assets.d'),
     Source.pattern('{PROJECT_DIR}/pubspec.yaml'),
   ];
 
   @override
   List<Source> get outputs => const <Source>[
-    Source.depfile('flutter_assets.d'),
     Source.pattern('{OUTPUT_DIR}/flutter_assets/kernel_blob.bin'),
   ];
 
   @override
+  List<String> get depfiles => const <String>[
+    'flutter_assets.d',
+  ];
+
+  @override
   Future<void> build(Environment environment) async {
     if (environment.defines[kBuildMode] == null) {
       throw MissingDefineException(kBuildMode, 'debug_bundle_linux_assets');
diff --git a/packages/flutter_tools/lib/src/build_system/targets/macos.dart b/packages/flutter_tools/lib/src/build_system/targets/macos.dart
index ca0f2cf..029b82f 100644
--- a/packages/flutter_tools/lib/src/build_system/targets/macos.dart
+++ b/packages/flutter_tools/lib/src/build_system/targets/macos.dart
@@ -245,14 +245,17 @@
   @override
   List<Source> get inputs => const <Source>[
     Source.pattern('{BUILD_DIR}/App.framework/App'),
-    Source.depfile('flutter_assets.d'),
   ];
 
   @override
   List<Source> get outputs => const <Source>[
     Source.pattern('{OUTPUT_DIR}/App.framework/Versions/A/App'),
     Source.pattern('{OUTPUT_DIR}/App.framework/Versions/A/Resources/Info.plist'),
-    Source.depfile('flutter_assets.d'),
+  ];
+
+  @override
+  List<String> get depfiles => const <String>[
+    'flutter_assets.d',
   ];
 
   @override
diff --git a/packages/flutter_tools/lib/src/build_system/targets/web.dart b/packages/flutter_tools/lib/src/build_system/targets/web.dart
index 11b01ec..531c71e 100644
--- a/packages/flutter_tools/lib/src/build_system/targets/web.dart
+++ b/packages/flutter_tools/lib/src/build_system/targets/web.dart
@@ -113,12 +113,14 @@
     Source.artifact(Artifact.engineDartBinary),
     Source.pattern('{BUILD_DIR}/main.dart'),
     Source.pattern('{PROJECT_DIR}/.packages'),
-    Source.depfile('dart2js.d'),
   ];
 
   @override
-  List<Source> get outputs => const <Source>[
-    Source.depfile('dart2js.d'),
+  List<Source> get outputs => const <Source>[];
+
+  @override
+  List<String> get depfiles => const <String>[
+    'dart2js.d',
   ];
 
   @override
@@ -187,14 +189,17 @@
     Source.pattern('{BUILD_DIR}/main.dart.js'),
     Source.pattern('{PROJECT_DIR}/pubspec.yaml'),
     Source.pattern('{PROJECT_DIR}/web/index.html'),
-    Source.depfile('flutter_assets.d'),
   ];
 
   @override
   List<Source> get outputs => const <Source>[
     Source.pattern('{OUTPUT_DIR}/main.dart.js'),
     Source.pattern('{OUTPUT_DIR}/index.html'),
-    Source.depfile('flutter_assets.d'),
+  ];
+
+  @override
+  List<String> get depfiles => const <String>[
+    'dart2js.d',
   ];
 
   @override
diff --git a/packages/flutter_tools/test/general.shard/build_system/build_system_test.dart b/packages/flutter_tools/test/general.shard/build_system/build_system_test.dart
index fa0e9a7..eb31522 100644
--- a/packages/flutter_tools/test/general.shard/build_system/build_system_test.dart
+++ b/packages/flutter_tools/test/general.shard/build_system/build_system_test.dart
@@ -319,8 +319,7 @@
       fs.file('a.txt').writeAsStringSync('a');
       called += 1;
     })
-      ..inputs = const <Source>[Source.depfile('example.d')]
-      ..outputs = const <Source>[Source.depfile('example.d')];
+      ..depfiles = <String>['example.d'];
     fs.file('b.txt').writeAsStringSync('b');
 
     await buildSystem.build(target, environment);
@@ -356,8 +355,7 @@
       }
       called += 1;
     })
-      ..inputs = const <Source>[Source.depfile('example.d')]
-      ..outputs = const <Source>[Source.depfile('example.d')];
+      ..depfiles = const <String>['example.d'];
     fs.file('b.txt').writeAsStringSync('b');
 
     await buildSystem.build(target, environment);
@@ -396,6 +394,9 @@
   List<Source> inputs = <Source>[];
 
   @override
+  List<String> depfiles = <String>[];
+
+  @override
   String name = 'test';
 
   @override
diff --git a/packages/flutter_tools/test/general.shard/build_system/source_test.dart b/packages/flutter_tools/test/general.shard/build_system/source_test.dart
index 6eb120d..fff21ce 100644
--- a/packages/flutter_tools/test/general.shard/build_system/source_test.dart
+++ b/packages/flutter_tools/test/general.shard/build_system/source_test.dart
@@ -160,45 +160,41 @@
   }));
 
   test('can resolve a missing depfile', () => testbed.run(() {
-    const Source depfile = Source.depfile('foo.d');
+    visitor.visitDepfile('foo.d');
 
-    depfile.accept(visitor);
     expect(visitor.sources, isEmpty);
     expect(visitor.containsNewDepfile, true);
   }));
 
   test('can resolve a populated depfile', () => testbed.run(() {
-    const Source depfile = Source.depfile('foo.d');
     environment.buildDir.childFile('foo.d')
       .writeAsStringSync('a.dart : c.dart');
 
-    depfile.accept(visitor);
+    visitor.visitDepfile('foo.d');
     expect(visitor.sources.single.path, 'c.dart');
     expect(visitor.containsNewDepfile, false);
 
     final SourceVisitor outputVisitor = SourceVisitor(environment, false);
-    depfile.accept(outputVisitor);
+    outputVisitor.visitDepfile('foo.d');
 
     expect(outputVisitor.sources.single.path, 'a.dart');
     expect(outputVisitor.containsNewDepfile, false);
   }));
 
   test('does not crash on completely invalid depfile', () => testbed.run(() {
-    const Source depfile = Source.depfile('foo.d');
     environment.buildDir.childFile('foo.d')
         .writeAsStringSync('hello, world');
 
-    depfile.accept(visitor);
+    visitor.visitDepfile('foo.d');
     expect(visitor.sources, isEmpty);
     expect(visitor.containsNewDepfile, false);
   }));
 
   test('can parse depfile with windows paths', () => testbed.run(() {
-    const Source depfile = Source.depfile('foo.d');
     environment.buildDir.childFile('foo.d')
         .writeAsStringSync(r'a.dart: C:\\foo\\bar.txt');
 
-    depfile.accept(visitor);
+    visitor.visitDepfile('foo.d');
     expect(visitor.sources.single.path, r'C:\foo\bar.txt');
     expect(visitor.containsNewDepfile, false);
   }, overrides: <Type, Generator>{
@@ -206,11 +202,10 @@
   }));
 
   test('can parse depfile with spaces in paths', () => testbed.run(() {
-    const Source depfile = Source.depfile('foo.d');
     environment.buildDir.childFile('foo.d')
         .writeAsStringSync(r'a.dart: foo\ bar.txt');
 
-    depfile.accept(visitor);
+    visitor.visitDepfile('foo.d');
     expect(visitor.sources.single.path, r'foo bar.txt');
     expect(visitor.containsNewDepfile, false);
   }));