Flutter tools support for kernel transformer tracking Widget creation locations. (#13997)

diff --git a/packages/flutter_tools/lib/src/android/gradle.dart b/packages/flutter_tools/lib/src/android/gradle.dart
index 5141261..e9598b6 100644
--- a/packages/flutter_tools/lib/src/android/gradle.dart
+++ b/packages/flutter_tools/lib/src/android/gradle.dart
@@ -300,6 +300,8 @@
   if (buildInfo.previewDart2) {
     command.add('-Ppreview-dart-2=true');
     command.add('-Pstrong=true');
+    if (buildInfo.trackWidgetCreation)
+      command.add('-Ptrack-widget-creation=true');
     if (buildInfo.extraFrontEndOptions != null)
       command.add('-Pextra-front-end-options=${buildInfo.extraFrontEndOptions}');
     if (buildInfo.extraGenSnapshotOptions != null)
diff --git a/packages/flutter_tools/lib/src/build_info.dart b/packages/flutter_tools/lib/src/build_info.dart
index 2598413..b552c8f 100644
--- a/packages/flutter_tools/lib/src/build_info.dart
+++ b/packages/flutter_tools/lib/src/build_info.dart
@@ -12,6 +12,7 @@
 class BuildInfo {
   const BuildInfo(this.mode, this.flavor,
       {this.previewDart2,
+      this.trackWidgetCreation,
       this.extraFrontEndOptions,
       this.extraGenSnapshotOptions,
       this.preferSharedLibrary,
@@ -29,6 +30,9 @@
   // Whether build should be done using Dart2 Frontend parser.
   final bool previewDart2;
 
+  /// Whether the build should track widget creation locations.
+  final bool trackWidgetCreation;
+
   /// Extra command-line options for front-end.
   final String extraFrontEndOptions;
 
@@ -68,6 +72,7 @@
   BuildInfo withTargetPlatform(TargetPlatform targetPlatform) =>
       new BuildInfo(mode, flavor,
           previewDart2: previewDart2,
+          trackWidgetCreation: trackWidgetCreation,
           extraFrontEndOptions: extraFrontEndOptions,
           extraGenSnapshotOptions: extraGenSnapshotOptions,
           preferSharedLibrary: preferSharedLibrary,
diff --git a/packages/flutter_tools/lib/src/commands/build_aot.dart b/packages/flutter_tools/lib/src/commands/build_aot.dart
index 1310169..fa20a92 100644
--- a/packages/flutter_tools/lib/src/commands/build_aot.dart
+++ b/packages/flutter_tools/lib/src/commands/build_aot.dart
@@ -341,6 +341,7 @@
       extraFrontEndOptions: extraFrontEndOptions,
       linkPlatformKernelIn : true,
       aot : true,
+      trackWidgetCreation: false,
     );
     if (mainPath == null) {
       printError('Compiler terminated unexpectedly.');
diff --git a/packages/flutter_tools/lib/src/commands/build_apk.dart b/packages/flutter_tools/lib/src/commands/build_apk.dart
index c088ca5..e384097 100644
--- a/packages/flutter_tools/lib/src/commands/build_apk.dart
+++ b/packages/flutter_tools/lib/src/commands/build_apk.dart
@@ -16,6 +16,7 @@
 
     argParser
       ..addFlag('preview-dart-2', negatable: false,  hide: !verboseHelp)
+      ..addFlag('track-widget-creation', negatable: false, hide: !verboseHelp)
       ..addFlag('prefer-shared-library', negatable: false,
           help: 'Whether to prefer compiling to a *.so file (android only).')
       ..addOption('target-platform',
diff --git a/packages/flutter_tools/lib/src/commands/build_flx.dart b/packages/flutter_tools/lib/src/commands/build_flx.dart
index be66079..57e39f8 100644
--- a/packages/flutter_tools/lib/src/commands/build_flx.dart
+++ b/packages/flutter_tools/lib/src/commands/build_flx.dart
@@ -21,6 +21,11 @@
     argParser.addOption('snapshot', defaultsTo: defaultSnapshotPath);
     argParser.addOption('depfile', defaultsTo: defaultDepfilePath);
     argParser.addFlag('preview-dart-2', negatable: false, hide: !verboseHelp);
+    argParser.addFlag(
+      'track-widget-creation',
+      hide: !verboseHelp,
+      help: 'Track widget creation locations. Requires Dart 2.0 functionality.',
+    );
     argParser.addOption('working-dir', defaultsTo: getAssetBuildDirectory());
     argParser.addFlag('report-licensed-packages', help: 'Whether to report the names of all the packages that are included in the application\'s LICENSE file.', defaultsTo: false);
     usesPubOption();
@@ -51,7 +56,8 @@
       workingDirPath: argResults['working-dir'],
       previewDart2: argResults['preview-dart-2'],
       precompiledSnapshot: argResults['precompiled'],
-      reportLicensedPackages: argResults['report-licensed-packages']
+      reportLicensedPackages: argResults['report-licensed-packages'],
+      trackWidgetCreation: argResults['track-widget-creation'],
     );
   }
 }
diff --git a/packages/flutter_tools/lib/src/commands/run.dart b/packages/flutter_tools/lib/src/commands/run.dart
index 888ef4d..4cf4b92 100644
--- a/packages/flutter_tools/lib/src/commands/run.dart
+++ b/packages/flutter_tools/lib/src/commands/run.dart
@@ -114,6 +114,9 @@
         hide: !verboseHelp,
         help: 'Turn on strong mode semantics.\n'
               'Valid only when --preview-dart-2 is also specified');
+    argParser.addFlag('track-widget-creation',
+        hide: !verboseHelp,
+        help: 'Track widget creation locations. Requires Dart 2.0 functionality.');
     argParser.addOption('project-root',
         hide: !verboseHelp,
         help: 'Specify the project root directory.');
@@ -297,7 +300,11 @@
     }
 
     final List<FlutterDevice> flutterDevices = devices.map((Device device) {
-      return new FlutterDevice(device, previewDart2: argResults['preview-dart-2']);
+      return new FlutterDevice(
+        device,
+        previewDart2: argResults['preview-dart-2'],
+        trackWidgetCreation: argResults['track-widget-creation'],
+      );
     }).toList();
 
     ResidentRunner runner;
diff --git a/packages/flutter_tools/lib/src/compile.dart b/packages/flutter_tools/lib/src/compile.dart
index ffa84fd..7635028 100644
--- a/packages/flutter_tools/lib/src/compile.dart
+++ b/packages/flutter_tools/lib/src/compile.dart
@@ -60,6 +60,7 @@
     String mainPath,
     bool linkPlatformKernelIn: false,
     bool aot: false,
+    bool trackWidgetCreation: false,
     List<String> extraFrontEndOptions,
     String incrementalCompilerByteStorePath,
     String packagesPath}) async {
@@ -77,6 +78,8 @@
     sdkRoot,
     '--strong',
   ];
+  if (trackWidgetCreation)
+    command.add('--track-widget-creation');
   if (!linkPlatformKernelIn)
     command.add('--no-link-platform');
   if (aot) {
@@ -118,12 +121,15 @@
 /// The wrapper is intended to stay resident in memory as user changes, reloads,
 /// restarts the Flutter app.
 class ResidentCompiler {
-  ResidentCompiler(this._sdkRoot) : assert(_sdkRoot != null) {
+  ResidentCompiler(this._sdkRoot, {bool trackWidgetCreation: false})
+    : assert(_sdkRoot != null),
+      _trackWidgetCreation = trackWidgetCreation {
     // This is a URI, not a file path, so the forward slash is correct even on Windows.
     if (!_sdkRoot.endsWith('/'))
       _sdkRoot = '$_sdkRoot/';
   }
 
+  final bool _trackWidgetCreation;
   String _sdkRoot;
   Process _server;
   final _StdoutHandler stdoutHandler = new _StdoutHandler();
@@ -162,6 +168,9 @@
       '--incremental',
       '--strong'
     ];
+    if (_trackWidgetCreation) {
+      args.add('--track-widget-creation');
+    }
     _server = await processManager.start(args);
     _server.stdout
       .transform(UTF8.decoder)
diff --git a/packages/flutter_tools/lib/src/flx.dart b/packages/flutter_tools/lib/src/flx.dart
index e3c286b..b2b0e4e 100644
--- a/packages/flutter_tools/lib/src/flx.dart
+++ b/packages/flutter_tools/lib/src/flx.dart
@@ -40,7 +40,8 @@
   String packagesPath,
   bool previewDart2 : false,
   bool precompiledSnapshot: false,
-  bool reportLicensedPackages: false
+  bool reportLicensedPackages: false,
+  bool trackWidgetCreation: false,
 }) async {
   outputPath ??= defaultFlxOutputPath;
   snapshotPath ??= defaultSnapshotPath;
@@ -73,6 +74,7 @@
       sdkRoot: artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath),
       incrementalCompilerByteStorePath: fs.path.absolute(getIncrementalCompilerByteStoreDirectory()),
       mainPath: fs.file(mainPath).absolute.path,
+      trackWidgetCreation: trackWidgetCreation,
     );
     if (kernelBinaryFilename == null) {
       throwToolExit('Compiler terminated unexpectedly on $mainPath');
diff --git a/packages/flutter_tools/lib/src/ios/simulators.dart b/packages/flutter_tools/lib/src/ios/simulators.dart
index 24037dc..86452b2 100644
--- a/packages/flutter_tools/lib/src/ios/simulators.dart
+++ b/packages/flutter_tools/lib/src/ios/simulators.dart
@@ -411,11 +411,15 @@
     await SimControl.instance.install(id, fs.path.absolute(bundle.path));
   }
 
-  Future<Null> _sideloadUpdatedAssetsForInstalledApplicationBundle(ApplicationPackage app, BuildInfo buildInfo) =>
-      // When running in previewDart2 mode, we still need to run compiler to
-      // produce kernel file for the application.
-      flx.build(precompiledSnapshot: !buildInfo.previewDart2,
-          previewDart2: buildInfo.previewDart2);
+  Future<Null> _sideloadUpdatedAssetsForInstalledApplicationBundle(ApplicationPackage app, BuildInfo buildInfo) {
+    // When running in previewDart2 mode, we still need to run compiler to
+    // produce kernel file for the application.
+    return flx.build(
+      precompiledSnapshot: !buildInfo.previewDart2,
+      previewDart2: buildInfo.previewDart2,
+      trackWidgetCreation: buildInfo.trackWidgetCreation,
+    );
+  }
 
   @override
   Future<bool> stopApp(ApplicationPackage app) async {
diff --git a/packages/flutter_tools/lib/src/resident_runner.dart b/packages/flutter_tools/lib/src/resident_runner.dart
index 7644cfc..9ac1d09 100644
--- a/packages/flutter_tools/lib/src/resident_runner.dart
+++ b/packages/flutter_tools/lib/src/resident_runner.dart
@@ -38,9 +38,16 @@
 
   StreamSubscription<String> _loggingSubscription;
 
-  FlutterDevice(this.device, { bool previewDart2 : false }) {
-    if (previewDart2)
-      generator = new ResidentCompiler(artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath));
+  FlutterDevice(this.device, {
+    bool previewDart2: false,
+    bool trackWidgetCreation: false,
+  }) {
+    if (previewDart2) {
+      generator = new ResidentCompiler(
+        artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath),
+        trackWidgetCreation: trackWidgetCreation,
+      );
+    }
   }
 
   String viewFilter;
diff --git a/packages/flutter_tools/lib/src/runner/flutter_command.dart b/packages/flutter_tools/lib/src/runner/flutter_command.dart
index fd21976..9d08b3e 100644
--- a/packages/flutter_tools/lib/src/runner/flutter_command.dart
+++ b/packages/flutter_tools/lib/src/runner/flutter_command.dart
@@ -170,11 +170,20 @@
       targetPlatform = getTargetPlatformForName(argResults['target-platform']);
     }
 
+    final bool trackWidgetCreation = argParser.options.containsKey('track-widget-creation')
+        ? argResults['track-widget-creation']
+        : false;
+    if (trackWidgetCreation == true && previewDart2 == false) {
+      throw new UsageException(
+          '--track-widget-creation is valid only when --preview-dart-2 is specified.', null);
+    }
+
     return new BuildInfo(getBuildMode(),
       argParser.options.containsKey('flavor')
         ? argResults['flavor']
         : null,
       previewDart2: previewDart2,
+      trackWidgetCreation: trackWidgetCreation,
       extraFrontEndOptions: argParser.options.containsKey(FlutterOptions.kExtraFrontEndOptions)
           ? argResults[FlutterOptions.kExtraFrontEndOptions]
           : null,