Friendlier flags for Dart compilation training. (#25645)

* Renamed --save-compilation-trace to flutter run --train.
* Renamed --precompile=<file> to --compilation-trace-file=<file>.
* In dynamic mode, made JIT snapshot the default, instead of kernel file.
diff --git a/packages/flutter_tools/gradle/flutter.gradle b/packages/flutter_tools/gradle/flutter.gradle
index 6feec96..0fcf949 100644
--- a/packages/flutter_tools/gradle/flutter.gradle
+++ b/packages/flutter_tools/gradle/flutter.gradle
@@ -318,8 +318,8 @@
             trackWidgetCreationValue = project.property('track-widget-creation').toBoolean()
         }
         String compilationTraceFilePathValue = null
-        if (project.hasProperty('precompile')) {
-            compilationTraceFilePathValue = project.property('precompile')
+        if (project.hasProperty('compilation-trace-file')) {
+            compilationTraceFilePathValue = project.property('compilation-trace-file')
         }
         Boolean createPatchValue = false
         if (project.hasProperty('patch')) {
@@ -535,7 +535,7 @@
                 args "--track-widget-creation"
             }
             if (compilationTraceFilePath != null) {
-                args "--precompile", compilationTraceFilePath
+                args "--compilation-trace-file", compilationTraceFilePath
             }
             if (createPatch) {
                 args "--patch"
diff --git a/packages/flutter_tools/lib/src/android/gradle.dart b/packages/flutter_tools/lib/src/android/gradle.dart
index 507446e..d07dbde 100644
--- a/packages/flutter_tools/lib/src/android/gradle.dart
+++ b/packages/flutter_tools/lib/src/android/gradle.dart
@@ -387,7 +387,7 @@
   assert(buildInfo.trackWidgetCreation != null);
   command.add('-Ptrack-widget-creation=${buildInfo.trackWidgetCreation}');
   if (buildInfo.compilationTraceFilePath != null)
-    command.add('-Pprecompile=${buildInfo.compilationTraceFilePath}');
+    command.add('-Pcompilation-trace-file=${buildInfo.compilationTraceFilePath}');
   if (buildInfo.createPatch)
     command.add('-Ppatch=true');
   if (buildInfo.extraFrontEndOptions != null)
diff --git a/packages/flutter_tools/lib/src/bundle.dart b/packages/flutter_tools/lib/src/bundle.dart
index 8f3ed1a..268ea49 100644
--- a/packages/flutter_tools/lib/src/bundle.dart
+++ b/packages/flutter_tools/lib/src/bundle.dart
@@ -73,6 +73,28 @@
   packagesPath ??= fs.path.absolute(PackageMap.globalPackagesPath);
   applicationKernelFilePath ??= getDefaultApplicationKernelPath(trackWidgetCreation: trackWidgetCreation);
 
+  if (compilationTraceFilePath != null) {
+    if (buildMode != BuildMode.dynamicProfile && buildMode != BuildMode.dynamicRelease) {
+      // Silently ignore JIT snapshotting for those builds that don't support it.
+      compilationTraceFilePath = null;
+
+    } else if (compilationTraceFilePath.isEmpty) {
+      // Disable JIT snapshotting if flag is empty.
+      printStatus('JIT snapshot will be disabled for this build...');
+      compilationTraceFilePath = null;
+
+    } else if (!fs.file(compilationTraceFilePath).existsSync()) {
+      // Be forgiving if compilation trace file is missing.
+      printError('Warning: Ignoring missing compiler training file $compilationTraceFilePath...');
+      printStatus('JIT snapshot will not use compiler training...');
+      final File tmp = fs.systemTempDirectory.childFile('flutterEmptyCompilationTrace.txt');
+      compilationTraceFilePath = (tmp..createSync(recursive: true)).path;
+
+    } else {
+      printStatus('JIT snapshot will use compiler training file $compilationTraceFilePath...');
+    }
+  }
+
   DevFSContent kernelContent;
   if (!precompiledSnapshot) {
     if ((extraFrontEndOptions != null) && extraFrontEndOptions.isNotEmpty)
diff --git a/packages/flutter_tools/lib/src/commands/build_bundle.dart b/packages/flutter_tools/lib/src/commands/build_bundle.dart
index c47c34c..6e2177f 100644
--- a/packages/flutter_tools/lib/src/commands/build_bundle.dart
+++ b/packages/flutter_tools/lib/src/commands/build_bundle.dart
@@ -94,7 +94,7 @@
       precompiledSnapshot: argResults['precompiled'],
       reportLicensedPackages: argResults['report-licensed-packages'],
       trackWidgetCreation: argResults['track-widget-creation'],
-      compilationTraceFilePath: argResults['precompile'],
+      compilationTraceFilePath: argResults['compilation-trace-file'],
       createPatch: argResults['patch'],
       buildNumber: buildNumber,
       baselineDir: argResults['baseline-dir'],
diff --git a/packages/flutter_tools/lib/src/commands/run.dart b/packages/flutter_tools/lib/src/commands/run.dart
index 138daa1..8964018 100644
--- a/packages/flutter_tools/lib/src/commands/run.dart
+++ b/packages/flutter_tools/lib/src/commands/run.dart
@@ -35,17 +35,17 @@
       ..addOption('route',
         help: 'Which route to load when running the app.',
       )
-      ..addFlag('save-compilation-trace',
+      ..addFlag('train',
         hide: !verboseHelp,
         negatable: false,
-        help: 'Save runtime compilation trace to a file.\n'
-              'Compilation trace will be saved to compilation.txt when \'flutter run\' exits. '
+        help: 'Save Dart runtime compilation trace to a file. '
+              'Compilation trace will be saved to a file specified by --compilation-trace-file '
+              'when \'flutter run --dynamic --profile --train\' exits. '
               'This file contains a list of Dart symbols that were compiled by the runtime JIT '
-              'compiler up to that point. This file can be used in later --dynamic builds to '
-              'precompile some code by the offline compiler, thus reducing application startup '
-              'latency at the cost of larger application package.\n'
-              'This flag is only allowed when running --dynamic --profile (recommended) or '
-              '--debug mode.\n'
+              'compiler up to that point. This file can be used in subsequent --dynamic builds '
+              'to precompile some code by the offline compiler. '
+              'This flag is only allowed when running as --dynamic --profile (recommended) or '
+              '--debug (may include unwanted debug symbols).'
       )
       ..addOption('target-platform',
         defaultsTo: 'default',
@@ -315,10 +315,10 @@
       }
     }
 
-    if (argResults['save-compilation-trace'] &&
+    if (argResults['train'] &&
         getBuildMode() != BuildMode.debug && getBuildMode() != BuildMode.dynamicProfile)
-      throwToolExit('Error: --save-compilation-trace is only allowed when running '
-          '--dynamic --profile (recommended) or --debug mode.');
+      throwToolExit('Error: --train is only allowed when running as --dynamic --profile '
+          '(recommended) or --debug (may include unwanted debug symbols).');
 
     final List<FlutterDevice> flutterDevices = devices.map<FlutterDevice>((Device device) {
       return FlutterDevice(
@@ -345,7 +345,7 @@
         projectRootPath: argResults['project-root'],
         packagesFilePath: globalResults['packages'],
         dillOutputPath: argResults['output-dill'],
-        saveCompilationTrace: argResults['save-compilation-trace'],
+        saveCompilationTrace: argResults['train'],
         stayResident: stayResident,
         ipv6: ipv6,
       );
@@ -358,7 +358,7 @@
         applicationBinary: applicationBinaryPath == null
             ? null
             : fs.file(applicationBinaryPath),
-        saveCompilationTrace: argResults['save-compilation-trace'],
+        saveCompilationTrace: argResults['train'],
         stayResident: stayResident,
         ipv6: ipv6,
       );
diff --git a/packages/flutter_tools/lib/src/runner/flutter_command.dart b/packages/flutter_tools/lib/src/runner/flutter_command.dart
index 9f05b00..06764b6 100644
--- a/packages/flutter_tools/lib/src/runner/flutter_command.dart
+++ b/packages/flutter_tools/lib/src/runner/flutter_command.dart
@@ -242,14 +242,13 @@
   }
 
   void addDynamicModeFlags({bool verboseHelp = false}) {
-    argParser.addOption('precompile',
+    argParser.addOption('compilation-trace-file',
+        defaultsTo: 'compilation.txt',
         hide: !verboseHelp,
-        help: 'Precompile functions specified in input file. This flag is only '
-              'allowed when using --dynamic. It takes a Dart compilation trace '
-              'file produced by the training run of the application. With this '
-              'flag, instead of using default Dart VM snapshot provided by the '
-              'engine, the application will use its own snapshot that includes '
-              'additional compiled functions.'
+        help: 'Filename of Dart compilation trace file. This file will be produced\n'
+              'by \'flutter run --dynamic --profile --train\' and consumed by subsequent\n'
+              '--dynamic builds such as \'flutter build apk --dynamic\' to precompile\n'
+              'some code by the offline compiler.'
     );
     argParser.addFlag('patch',
         hide: !verboseHelp,
@@ -381,8 +380,8 @@
         ? argResults['flavor']
         : null,
       trackWidgetCreation: trackWidgetCreation,
-      compilationTraceFilePath: argParser.options.containsKey('precompile')
-          ? argResults['precompile']
+      compilationTraceFilePath: argParser.options.containsKey('compilation-trace-file')
+          ? argResults['compilation-trace-file']
           : null,
       createBaseline: argParser.options.containsKey('baseline')
           ? argResults['baseline']
@@ -647,23 +646,23 @@
 
     final bool dynamicFlag = argParser.options.containsKey('dynamic')
         ? argResults['dynamic'] : false;
-    final String compilationTraceFilePath = argParser.options.containsKey('precompile')
-        ? argResults['precompile'] : null;
+    final String compilationTraceFilePath = argParser.options.containsKey('compilation-trace-file')
+        ? argResults['compilation-trace-file'] : null;
     final bool createBaseline = argParser.options.containsKey('baseline')
         ? argResults['baseline'] : false;
     final bool createPatch = argParser.options.containsKey('patch')
         ? argResults['patch'] : false;
 
-    if (compilationTraceFilePath != null && getBuildMode() == BuildMode.debug)
-      throw ToolExit('Error: --precompile is not allowed when --debug is specified.');
-    if (compilationTraceFilePath != null && !dynamicFlag)
-      throw ToolExit('Error: --precompile is allowed only when --dynamic is specified.');
     if (createBaseline && createPatch)
       throw ToolExit('Error: Only one of --baseline, --patch is allowed.');
+    if (createBaseline && !dynamicFlag)
+      throw ToolExit('Error: --baseline is allowed only when --dynamic is specified.');
     if (createBaseline && compilationTraceFilePath == null)
-      throw ToolExit('Error: --baseline is allowed only when --precompile is specified.');
+      throw ToolExit('Error: --baseline requires --compilation-trace-file to be specified.');
+    if (createPatch && !dynamicFlag)
+      throw ToolExit('Error: --patch is allowed only when --dynamic is specified.');
     if (createPatch && compilationTraceFilePath == null)
-      throw ToolExit('Error: --patch is allowed only when --precompile is specified.');
+      throw ToolExit('Error: --patch requires --compilation-trace-file to be specified.');
   }
 
   ApplicationPackageStore applicationPackages;