Include .track in file names for cached dill files for builds with --track-widget-creation (#23299)

Ensure that cached dill files for builds with --track-widget-creation
always have .track. in the file name to avoid mixing transformed and
untransformed kernel files.
diff --git a/packages/flutter_tools/test/compile_test.dart b/packages/flutter_tools/test/compile_test.dart
index 7c74e3e..686fd0f 100644
--- a/packages/flutter_tools/test/compile_test.dart
+++ b/packages/flutter_tools/test/compile_test.dart
@@ -48,7 +48,8 @@
             ))
           ));
       final CompilerOutput output = await kernelCompiler.compile(sdkRoot: '/path/to/sdkroot',
-        mainPath: '/path/to/main.dart'
+        mainPath: '/path/to/main.dart',
+        trackWidgetCreation: false,
       );
       expect(mockFrontendServerStdIn.getAndClear(), isEmpty);
       expect(logger.errorText, equals('\nCompiler message:\nline1\nline2\n'));
@@ -70,7 +71,8 @@
           ));
 
       final CompilerOutput output = await kernelCompiler.compile(sdkRoot: '/path/to/sdkroot',
-        mainPath: '/path/to/main.dart'
+        mainPath: '/path/to/main.dart',
+        trackWidgetCreation: false,
       );
       expect(mockFrontendServerStdIn.getAndClear(), isEmpty);
       expect(logger.errorText, equals('\nCompiler message:\nline1\nline2\n'));
@@ -93,8 +95,10 @@
           ))
       ));
 
-      final CompilerOutput output = await kernelCompiler.compile(sdkRoot: '/path/to/sdkroot',
-          mainPath: '/path/to/main.dart'
+      final CompilerOutput output = await kernelCompiler.compile(
+        sdkRoot: '/path/to/sdkroot',
+        mainPath: '/path/to/main.dart',
+        trackWidgetCreation: false,
       );
       expect(mockFrontendServerStdIn.getAndClear(), isEmpty);
       expect(logger.errorText, equals('\nCompiler message:\nline1\nline2\n'));
@@ -149,7 +153,9 @@
           ));
 
       final CompilerOutput output = await generator.recompile(
-        '/path/to/main.dart', null /* invalidatedFiles */
+        '/path/to/main.dart',
+          null /* invalidatedFiles */,
+        outputPath: '/build/',
       );
       expect(mockFrontendServerStdIn.getAndClear(), 'compile /path/to/main.dart\n');
       verifyNoMoreInteractions(mockFrontendServerStdIn);
@@ -167,7 +173,9 @@
       );
 
       final CompilerOutput output = await generator.recompile(
-          '/path/to/main.dart', null /* invalidatedFiles */
+        '/path/to/main.dart',
+        null, /* invalidatedFiles */
+        outputPath: '/build/',
       );
       expect(output, equals(null));
     }, overrides: <Type, Generator>{
@@ -183,7 +191,11 @@
       when(mockFrontendServer.stdout)
           .thenAnswer((Invocation invocation) => streamController.stream);
       streamController.add(utf8.encode('result abc\nline0\nline1\nabc /path/to/main.dart.dill 0\n'));
-      await generator.recompile('/path/to/main.dart', null /* invalidatedFiles */);
+      await generator.recompile(
+        '/path/to/main.dart',
+        null, /* invalidatedFiles */
+        outputPath: '/build/',
+      );
       expect(mockFrontendServerStdIn.getAndClear(), 'compile /path/to/main.dart\n');
 
       await _recompile(streamController, generator, mockFrontendServerStdIn,
@@ -210,7 +222,7 @@
       streamController.add(utf8.encode(
         'result abc\nline0\nline1\nabc /path/to/main.dart.dill 0\n'
       ));
-      await generator.recompile('/path/to/main.dart', null /* invalidatedFiles */);
+      await generator.recompile('/path/to/main.dart', null /* invalidatedFiles */, outputPath: '/build/');
       expect(mockFrontendServerStdIn.getAndClear(), 'compile /path/to/main.dart\n');
 
       await _recompile(streamController, generator, mockFrontendServerStdIn,
@@ -292,7 +304,9 @@
       )));
 
       await generator.recompile(
-          '/path/to/main.dart', null /* invalidatedFiles */
+        '/path/to/main.dart',
+        null, /* invalidatedFiles */
+        outputPath: '/build/',
       ).then((CompilerOutput output) {
         expect(mockFrontendServerStdIn.getAndClear(),
             'compile /path/to/main.dart\n');
@@ -339,7 +353,9 @@
 
       // The test manages timing via completers.
       generator.recompile( // ignore: unawaited_futures
-          '/path/to/main.dart', null /* invalidatedFiles */
+        '/path/to/main.dart',
+        null, /* invalidatedFiles */
+        outputPath: '/build/',
       ).then((CompilerOutput outputCompile) {
         expect(logger.errorText,
             equals('\nCompiler message:\nline1\nline2\n'));
@@ -394,7 +410,11 @@
   scheduleMicrotask(() {
     streamController.add(utf8.encode(mockCompilerOutput));
   });
-  final CompilerOutput output = await generator.recompile(null /* mainPath */, <String>['/path/to/main.dart']);
+  final CompilerOutput output = await generator.recompile(
+    null /* mainPath */,
+    <String>['/path/to/main.dart'],
+    outputPath: '/build/',
+  );
   expect(output.outputFilename, equals('/path/to/main.dart.dill'));
   final String commands = mockFrontendServerStdIn.getAndClear();
   final RegExp re = RegExp('^recompile (.*)\\n/path/to/main.dart\\n(.*)\\n\$');
diff --git a/packages/flutter_tools/test/devfs_test.dart b/packages/flutter_tools/test/devfs_test.dart
index ed4ad97..8aebeb0 100644
--- a/packages/flutter_tools/test/devfs_test.dart
+++ b/packages/flutter_tools/test/devfs_test.dart
@@ -119,13 +119,25 @@
       devFSOperations.expectMessages(<String>['create test']);
       expect(devFS.assetPathsToEvict, isEmpty);
 
-      final int bytes = await devFS.update(
+      int bytes = await devFS.update(
         mainPath: 'lib/foo.txt',
         generator: residentCompiler,
         pathToReload: 'lib/foo.txt.dill',
+        trackWidgetCreation: false,
       );
       devFSOperations.expectMessages(<String>[
-        'writeFile test lib/foo.txt.dill',
+        'writeFile test lib/foo.txt.dill build/app.dill',
+      ]);
+      expect(devFS.assetPathsToEvict, isEmpty);
+
+      bytes = await devFS.update(
+        mainPath: 'lib/foo.txt',
+        generator: residentCompiler,
+        pathToReload: 'lib/foo.txt.dill',
+        trackWidgetCreation: true,
+      );
+      devFSOperations.expectMessages(<String>[
+        'writeFile test lib/foo.txt.dill build/app.dill.track.dill',
       ]);
       expect(devFS.assetPathsToEvict, isEmpty);
 
@@ -142,9 +154,10 @@
         mainPath: 'lib/foo.txt',
         generator: residentCompiler,
         pathToReload: 'lib/foo.txt.dill',
+        trackWidgetCreation: false,
       );
       devFSOperations.expectMessages(<String>[
-        'writeFile test lib/foo.txt.dill',
+        'writeFile test lib/foo.txt.dill build/app.dill',
       ]);
       expect(devFS.assetPathsToEvict, isEmpty);
       expect(bytes, 22);
@@ -157,9 +170,10 @@
         mainPath: 'lib/foo.txt',
         generator: residentCompiler,
         pathToReload: 'lib/foo.txt.dill',
+        trackWidgetCreation: false,
       );
       devFSOperations.expectMessages(<String>[
-        'writeFile test lib/foo.txt.dill',
+        'writeFile test lib/foo.txt.dill build/app.dill',
       ]);
       expect(devFS.assetPathsToEvict, isEmpty);
       expect(bytes, 22);
@@ -171,9 +185,10 @@
         mainPath: 'lib/foo.txt',
         generator: residentCompiler,
         pathToReload: 'lib/foo.txt.dill',
+        trackWidgetCreation: false,
       );
       devFSOperations.expectMessages(<String>[
-        'writeFile test lib/foo.txt.dill',
+        'writeFile test lib/foo.txt.dill build/app.dill',
       ]);
       expect(devFS.assetPathsToEvict, isEmpty);
       expect(bytes, 22);
@@ -183,12 +198,41 @@
         mainPath: 'lib/foo.txt',
         generator: residentCompiler,
         pathToReload: 'lib/foo.txt.dill',
+        trackWidgetCreation: false,
       );
       devFSOperations.expectMessages(<String>[
-        'writeFile test lib/foo.txt.dill',
+        'writeFile test lib/foo.txt.dill build/app.dill',
       ]);
       expect(devFS.assetPathsToEvict, isEmpty);
       expect(bytes, 22);
+
+      // Set the last modified time to 5 seconds in the past.
+      updateFileModificationTime(file.path, DateTime.now(), -5);
+      bytes = await devFS.update(
+        mainPath: 'lib/foo.txt',
+        generator: residentCompiler,
+        pathToReload: 'lib/foo.txt.dill',
+        trackWidgetCreation: true,
+      );
+      devFSOperations.expectMessages(<String>[
+        'writeFile test lib/foo.txt.dill build/app.dill.track.dill',
+      ]);
+      expect(devFS.assetPathsToEvict, isEmpty);
+      expect(bytes, 22);
+
+      await file.writeAsBytes(<int>[1, 2, 3, 4, 5, 6]);
+      bytes = await devFS.update(
+        mainPath: 'lib/foo.txt',
+        generator: residentCompiler,
+        pathToReload: 'lib/foo.txt.dill',
+        trackWidgetCreation: true,
+      );
+      devFSOperations.expectMessages(<String>[
+        'writeFile test lib/foo.txt.dill build/app.dill.track.dill',
+      ]);
+      expect(devFS.assetPathsToEvict, isEmpty);
+      expect(bytes, 22);
+
     }, overrides: <Type, Generator>{
       FileSystem: () => fs,
     });
@@ -200,10 +244,11 @@
         mainPath: 'lib/foo.txt',
         generator: residentCompiler,
         pathToReload: 'lib/foo.txt.dill',
+        trackWidgetCreation: false,
       );
       devFSOperations.expectMessages(<String>[
         'deleteFile test lib/foo.txt',
-        'writeFile test lib/foo.txt.dill',
+        'writeFile test lib/foo.txt.dill build/app.dill',
       ]);
       expect(devFS.assetPathsToEvict, isEmpty);
       expect(bytes, 22);
@@ -213,16 +258,30 @@
 
     testUsingContext('add new package', () async {
       await _createPackage(fs, 'newpkg', 'anotherfile.txt');
-      final int bytes = await devFS.update(
+      int bytes = await devFS.update(
         mainPath: 'lib/foo.txt',
         generator: residentCompiler,
         pathToReload: 'lib/foo.txt.dill',
+        trackWidgetCreation: false,
       );
       devFSOperations.expectMessages(<String>[
-        'writeFile test lib/foo.txt.dill',
+        'writeFile test lib/foo.txt.dill build/app.dill',
       ]);
       expect(devFS.assetPathsToEvict, isEmpty);
       expect(bytes, 22);
+
+      bytes = await devFS.update(
+        mainPath: 'lib/foo.txt',
+        generator: residentCompiler,
+        pathToReload: 'lib/foo.txt.dill',
+        trackWidgetCreation: true,
+      );
+      devFSOperations.expectMessages(<String>[
+        'writeFile test lib/foo.txt.dill build/app.dill.track.dill',
+      ]);
+      expect(devFS.assetPathsToEvict, isEmpty);
+      expect(bytes, 22);
+
     }, overrides: <Type, Generator>{
       FileSystem: () => fs,
     });
@@ -248,9 +307,10 @@
         fileFilter: fileFilter,
         generator: residentCompiler,
         pathToReload: 'lib/foo.txt.dill',
+        trackWidgetCreation: false,
       );
       devFSOperations.expectMessages(<String>[
-        'writeFile test lib/foo.txt.dill',
+        'writeFile test lib/foo.txt.dill build/app.dill',
       ]);
       expect(devFS.assetPathsToEvict, isEmpty);
       expect(bytes, 22);
@@ -266,10 +326,11 @@
         bundleDirty: true,
         generator: residentCompiler,
         pathToReload: 'lib/foo.txt.dill',
+        trackWidgetCreation: false,
       );
       devFSOperations.expectMessages(<String>[
         'writeFile test ${_inAssetBuildDirectory(fs, 'a.txt')}',
-        'writeFile test lib/foo.txt.dill',
+        'writeFile test lib/foo.txt.dill build/app.dill',
       ]);
       expect(devFS.assetPathsToEvict, unorderedMatches(<String>['a.txt']));
       devFS.assetPathsToEvict.clear();
@@ -286,12 +347,13 @@
         bundleDirty: true,
         generator: residentCompiler,
         pathToReload: 'lib/foo.txt.dill',
+        trackWidgetCreation: false,
       );
       // Expect entire asset bundle written because bundleDirty is true
       devFSOperations.expectMessages(<String>[
         'writeFile test ${_inAssetBuildDirectory(fs, 'a.txt')}',
         'writeFile test ${_inAssetBuildDirectory(fs, 'b.txt')}',
-        'writeFile test lib/foo.txt.dill',
+        'writeFile test lib/foo.txt.dill build/app.dill',
       ]);
       expect(devFS.assetPathsToEvict, unorderedMatches(<String>[
         'a.txt', 'b.txt']));
@@ -308,10 +370,11 @@
         bundle: assetBundle,
         generator: residentCompiler,
         pathToReload: 'lib/foo.txt.dill',
+        trackWidgetCreation: false,
       );
       devFSOperations.expectMessages(<String>[
         'writeFile test ${_inAssetBuildDirectory(fs, 'c.txt')}',
-        'writeFile test lib/foo.txt.dill',
+        'writeFile test lib/foo.txt.dill build/app.dill',
       ]);
       expect(devFS.assetPathsToEvict, unorderedMatches(<String>[
         'c.txt']));
@@ -328,10 +391,11 @@
         bundle: assetBundle,
         generator: residentCompiler,
         pathToReload: 'lib/foo.txt.dill',
+        trackWidgetCreation: false,
       );
       devFSOperations.expectMessages(<String>[
         'deleteFile test ${_inAssetBuildDirectory(fs, 'c.txt')}',
-        'writeFile test lib/foo.txt.dill',
+        'writeFile test lib/foo.txt.dill build/app.dill',
       ]);
       expect(devFS.assetPathsToEvict, unorderedMatches(<String>['c.txt']));
       devFS.assetPathsToEvict.clear();
@@ -348,11 +412,12 @@
         bundleDirty: true,
         generator: residentCompiler,
         pathToReload: 'lib/foo.txt.dill',
+        trackWidgetCreation: false,
       );
       devFSOperations.expectMessages(<String>[
         'deleteFile test ${_inAssetBuildDirectory(fs, 'a.txt')}',
         'deleteFile test ${_inAssetBuildDirectory(fs, 'b.txt')}',
-        'writeFile test lib/foo.txt.dill',
+        'writeFile test lib/foo.txt.dill build/app.dill',
       ]);
       expect(devFS.assetPathsToEvict, unorderedMatches(<String>[
         'a.txt', 'b.txt'
@@ -405,6 +470,7 @@
         mainPath: 'lib/foo.txt',
         generator: residentCompiler,
         pathToReload: 'lib/foo.txt.dill',
+        trackWidgetCreation: false,
       );
       vmService.expectMessages(<String>[
         'writeFile test lib/foo.txt.dill',
diff --git a/packages/flutter_tools/test/src/mocks.dart b/packages/flutter_tools/test/src/mocks.dart
index e2b24d9..9278c55 100644
--- a/packages/flutter_tools/test/src/mocks.dart
+++ b/packages/flutter_tools/test/src/mocks.dart
@@ -427,7 +427,11 @@
 
   @override
   Future<dynamic> writeFile(String fsName, Uri deviceUri, DevFSContent content) async {
-    messages.add('writeFile $fsName $deviceUri');
+    String message = 'writeFile $fsName $deviceUri';
+    if (content is DevFSFileContent) {
+      message += ' ${content.file.path}';
+    }
+    messages.add(message);
     devicePathToContent[deviceUri] = content;
   }