[flutter_tool] Teach the tool about local engine Fuchsia artifacts (#43759)

diff --git a/packages/flutter_tools/lib/src/artifacts.dart b/packages/flutter_tools/lib/src/artifacts.dart
index fa12f56..ba0e235 100644
--- a/packages/flutter_tools/lib/src/artifacts.dart
+++ b/packages/flutter_tools/lib/src/artifacts.dart
@@ -61,8 +61,6 @@
 
   // Fuchsia artifacts from the engine prebuilts.
   fuchsiaKernelCompiler,
-  fuchsiaPlatformDill,
-  fuchsiaPatchedSdk,
   fuchsiaFlutterJitRunner,
 }
 
@@ -138,10 +136,6 @@
       return 'flutter_ddc_sdk.dill';
     case Artifact.fuchsiaKernelCompiler:
       return 'kernel_compiler.snapshot';
-    case Artifact.fuchsiaPlatformDill:
-      return 'platform_strong.dill';
-    case Artifact.fuchsiaPatchedSdk:
-      return 'flutter_runner_patched_sdk';
     case Artifact.fuchsiaFlutterJitRunner:
       if (mode == BuildMode.debug || mode == BuildMode.profile) {
         return 'flutter_jit_runner-0.far';
@@ -245,18 +239,17 @@
         final String hostPlatform = getNameForHostPlatform(getCurrentHostPlatform());
         return fs.path.join(engineDir, hostPlatform, _artifactToFileName(artifact));
       default:
-        assert(false, 'Artifact $artifact not available for platform $platform.');
-        return null;
+        return _getHostArtifactPath(artifact, platform, mode);
     }
   }
 
   String _getIosArtifactPath(Artifact artifact, TargetPlatform platform, BuildMode mode) {
-    final String artifactFileName = _artifactToFileName(artifact);
     switch (artifact) {
       case Artifact.genSnapshot:
       case Artifact.snapshotDart:
       case Artifact.flutterFramework:
       case Artifact.frontendServerSnapshotForEngineDartSdk:
+        final String artifactFileName = _artifactToFileName(artifact);
         final String engineDir = _getEngineArtifactsPath(platform, mode);
         return fs.path.join(engineDir, artifactFileName);
       case Artifact.ideviceId:
@@ -264,21 +257,23 @@
       case Artifact.idevicescreenshot:
       case Artifact.idevicesyslog:
       case Artifact.idevicename:
+        final String artifactFileName = _artifactToFileName(artifact);
         return cache.getArtifactDirectory('libimobiledevice').childFile(artifactFileName).path;
       case Artifact.iosDeploy:
+        final String artifactFileName = _artifactToFileName(artifact);
         return cache.getArtifactDirectory('ios-deploy').childFile(artifactFileName).path;
       case Artifact.ideviceinstaller:
+        final String artifactFileName = _artifactToFileName(artifact);
         return cache.getArtifactDirectory('ideviceinstaller').childFile(artifactFileName).path;
       case Artifact.iproxy:
+        final String artifactFileName = _artifactToFileName(artifact);
         return cache.getArtifactDirectory('usbmuxd').childFile(artifactFileName).path;
       default:
-        assert(false, 'Artifact $artifact not available for platform $platform.');
-        return null;
+        return _getHostArtifactPath(artifact, platform, mode);
     }
   }
 
   String _getFuchsiaArtifactPath(Artifact artifact, TargetPlatform platform, BuildMode mode) {
-    final String artifactFileName = _artifactToFileName(artifact, platform, mode);
     final String root = fs.path.join(
       cache.getArtifactDirectory('flutter_runner').path,
       'flutter',
@@ -286,16 +281,20 @@
       getNameForBuildMode(mode),
     );
     switch (artifact) {
-      case Artifact.fuchsiaKernelCompiler:
-        return fs.path.join(root, 'jit', 'dart_binaries', artifactFileName);
-      case Artifact.fuchsiaPlatformDill:
+      case Artifact.flutterPatchedSdkPath:
+        const String artifactFileName = 'flutter_runner_patched_sdk';
+        return fs.path.join(root, 'jit', artifactFileName);
+      case Artifact.platformKernelDill:
+        final String artifactFileName = _artifactToFileName(artifact, platform, mode);
         return fs.path.join(root, 'jit', 'flutter_runner_patched_sdk', artifactFileName);
-      case Artifact.fuchsiaPatchedSdk:
+      case Artifact.fuchsiaKernelCompiler:
+        final String artifactFileName = _artifactToFileName(artifact, platform, mode);
+        return fs.path.join(root, 'jit', 'dart_binaries', artifactFileName);
       case Artifact.fuchsiaFlutterJitRunner:
+        final String artifactFileName = _artifactToFileName(artifact, platform, mode);
         return fs.path.join(root, 'jit', artifactFileName);
       default:
-        assert(false, 'Artifact $artifact not available for platform $platform.');
-        return null;
+        return _getHostArtifactPath(artifact, platform, mode);
     }
   }
 
@@ -423,6 +422,9 @@
       case Artifact.vmSnapshotData:
         return fs.path.join(engineOutPath, 'gen', 'flutter', 'lib', 'snapshot', artifactFileName);
       case Artifact.platformKernelDill:
+        if (platform == TargetPlatform.fuchsia_x64 || platform == TargetPlatform.fuchsia_arm64) {
+          return fs.path.join(engineOutPath, 'flutter_runner_patched_sdk', artifactFileName);
+        }
         return fs.path.join(_getFlutterPatchedSdkPath(mode), artifactFileName);
       case Artifact.platformLibrariesJson:
         return fs.path.join(_getFlutterPatchedSdkPath(mode), 'lib', artifactFileName);
@@ -435,6 +437,9 @@
         // what was specified in [mode] argument because local engine will
         // have only one flutter_patched_sdk in standard location, that
         // is happen to be what debug(non-release) mode is using.
+        if (platform == TargetPlatform.fuchsia_x64 || platform == TargetPlatform.fuchsia_arm64) {
+          return fs.path.join(engineOutPath, 'flutter_runner_patched_sdk');
+        }
         return _getFlutterPatchedSdkPath(BuildMode.debug);
       case Artifact.flutterWebSdk:
         return _getFlutterWebSdkPath();
@@ -473,11 +478,14 @@
       case Artifact.webPlatformKernelDill:
         return fs.path.join(_getFlutterWebSdkPath(), 'kernel', _artifactToFileName(artifact));
       case Artifact.fuchsiaKernelCompiler:
-      case Artifact.fuchsiaPlatformDill:
-      case Artifact.fuchsiaPatchedSdk:
+        final String hostPlatform = getNameForHostPlatform(getCurrentHostPlatform());
+        final String dartBinaries = 'dart_binaries-$mode-$hostPlatform';
+        return fs.path.join(engineOutPath, 'host_bundle', dartBinaries, 'kernel_compiler.dart.snapshot');
       case Artifact.fuchsiaFlutterJitRunner:
-        assert(false, 'Invalid local engine artifact $artifact.');
-        return null;
+        if (mode == BuildMode.debug || mode == BuildMode.profile) {
+          return fs.path.join(engineOutPath, 'flutter_jit_runner-0.far');
+        }
+        return fs.path.join(engineOutPath, 'flutter_jit_product_runner-0.far');
     }
     assert(false, 'Invalid artifact $artifact.');
     return null;
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 25236e2..19de36b 100644
--- a/packages/flutter_tools/lib/src/build_system/build_system.dart
+++ b/packages/flutter_tools/lib/src/build_system/build_system.dart
@@ -575,6 +575,9 @@
   final String target;
   final dynamic exception;
   final StackTrace stackTrace;
+
+  @override
+  String toString() => 'target: $target\nexception:$exception\n$stackTrace';
 }
 
 /// Helper class to collect measurement data.
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 ed4945f..13cc4e0 100644
--- a/packages/flutter_tools/lib/src/build_system/targets/dart.dart
+++ b/packages/flutter_tools/lib/src/build_system/targets/dart.dart
@@ -207,19 +207,33 @@
     if (environment.defines[kBuildMode] == null) {
       throw MissingDefineException(kBuildMode, 'kernel_snapshot');
     }
+    if (environment.defines[kTargetPlatform] == null) {
+      throw MissingDefineException(kTargetPlatform, 'kernel_snapshot');
+    }
     final BuildMode buildMode = getBuildModeForName(environment.defines[kBuildMode]);
     final String targetFile = environment.defines[kTargetFile] ?? fs.path.join('lib', 'main.dart');
     final String packagesPath = environment.projectDir.childFile('.packages').path;
     final String targetFileAbsolute = fs.file(targetFile).absolute.path;
     // everything besides 'false' is considered to be enabled.
     final bool trackWidgetCreation = environment.defines[kTrackWidgetCreation] != 'false';
+    final TargetPlatform targetPlatform = getTargetPlatformForName(environment.defines[kTargetPlatform]);
+
+    TargetModel targetModel = TargetModel.flutter;
+    if (targetPlatform == TargetPlatform.fuchsia_x64 ||
+        targetPlatform == TargetPlatform.fuchsia_arm64) {
+      targetModel = TargetModel.flutterRunner;
+    }
 
     final CompilerOutput output = await compiler.compile(
-      sdkRoot: artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath, mode: buildMode),
+      sdkRoot: artifacts.getArtifactPath(
+        Artifact.flutterPatchedSdkPath,
+        platform: targetPlatform,
+        mode: buildMode,
+      ),
       aot: buildMode != BuildMode.debug,
       buildMode: buildMode,
       trackWidgetCreation: trackWidgetCreation && buildMode == BuildMode.debug,
-      targetModel: TargetModel.flutter,
+      targetModel: targetModel,
       outputFilePath: environment.buildDir.childFile('app.dill').path,
       packagesPath: packagesPath,
       linkPlatformKernelIn: buildMode == BuildMode.release,
diff --git a/packages/flutter_tools/lib/src/codegen.dart b/packages/flutter_tools/lib/src/codegen.dart
index 6703dd1..bd66869 100644
--- a/packages/flutter_tools/lib/src/codegen.dart
+++ b/packages/flutter_tools/lib/src/codegen.dart
@@ -171,10 +171,15 @@
     String outputPath,
     String initializeFromDill,
     bool runCold = false,
+    TargetPlatform targetPlatform,
   }) async {
     codeGenerator.updatePackages(flutterProject);
     final ResidentCompiler residentCompiler = ResidentCompiler(
-      artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath),
+      artifacts.getArtifactPath(
+        Artifact.flutterPatchedSdkPath,
+        platform: targetPlatform,
+        mode: buildMode,
+      ),
       buildMode: buildMode,
       trackWidgetCreation: trackWidgetCreation,
       packagesPath: PackageMap.globalGeneratedPackagesPath,
diff --git a/packages/flutter_tools/lib/src/fuchsia/fuchsia_device.dart b/packages/flutter_tools/lib/src/fuchsia/fuchsia_device.dart
index 07be37c..142a7b9 100644
--- a/packages/flutter_tools/lib/src/fuchsia/fuchsia_device.dart
+++ b/packages/flutter_tools/lib/src/fuchsia/fuchsia_device.dart
@@ -433,24 +433,6 @@
   void clearLogs() {}
 
   @override
-  OverrideArtifacts get artifactOverrides {
-    return _artifactOverrides ??= OverrideArtifacts(
-      parent: Artifacts.instance,
-      platformKernelDill: fs.file(artifacts.getArtifactPath(
-        Artifact.fuchsiaPlatformDill,
-        platform: TargetPlatform.fuchsia_x64,
-        mode: BuildMode.debug,
-      )),
-      flutterPatchedSdk: fs.file(artifacts.getArtifactPath(
-        Artifact.fuchsiaPatchedSdk,
-        platform: TargetPlatform.fuchsia_x64,
-        mode: BuildMode.debug,
-      )),
-    );
-  }
-  OverrideArtifacts _artifactOverrides;
-
-  @override
   bool get supportsScreenshot => false;
 
   bool get ipv6 {
diff --git a/packages/flutter_tools/lib/src/fuchsia/fuchsia_kernel_compiler.dart b/packages/flutter_tools/lib/src/fuchsia/fuchsia_kernel_compiler.dart
index aabe9a8..48caeca 100644
--- a/packages/flutter_tools/lib/src/fuchsia/fuchsia_kernel_compiler.dart
+++ b/packages/flutter_tools/lib/src/fuchsia/fuchsia_kernel_compiler.dart
@@ -38,13 +38,13 @@
     final String kernelCompiler = artifacts.getArtifactPath(
       Artifact.fuchsiaKernelCompiler,
       platform: TargetPlatform.fuchsia_x64,  // This file is not arch-specific.
-      mode: BuildMode.debug,
+      mode: buildInfo.mode,
     );
     if (!fs.isFileSync(kernelCompiler)) {
       throwToolExit('Fuchisa kernel compiler not found at "$kernelCompiler"');
     }
     final String platformDill = artifacts.getArtifactPath(
-      Artifact.fuchsiaPlatformDill,
+      Artifact.platformKernelDill,
       platform: TargetPlatform.fuchsia_x64,  // This file is not arch-specific.
       mode: buildInfo.mode,
     );
@@ -92,7 +92,7 @@
 
     final List<String> command = <String>[
       artifacts.getArtifactPath(Artifact.engineDartBinary),
-      artifacts.getArtifactPath(Artifact.fuchsiaKernelCompiler),
+      kernelCompiler,
       ...flags,
     ];
     final Process process = await processUtils.start(command);
diff --git a/packages/flutter_tools/lib/src/resident_runner.dart b/packages/flutter_tools/lib/src/resident_runner.dart
index 6de86aa..c48d2a6 100644
--- a/packages/flutter_tools/lib/src/resident_runner.dart
+++ b/packages/flutter_tools/lib/src/resident_runner.dart
@@ -37,12 +37,17 @@
     this.fileSystemScheme,
     this.viewFilter,
     TargetModel targetModel = TargetModel.flutter,
+    TargetPlatform targetPlatform,
     List<String> experimentalFlags,
     ResidentCompiler generator,
     @required BuildMode buildMode,
   }) : assert(trackWidgetCreation != null),
        generator = generator ?? ResidentCompiler(
-         artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath, mode: buildMode),
+         artifacts.getArtifactPath(
+           Artifact.flutterPatchedSdkPath,
+           platform: targetPlatform,
+           mode: buildMode,
+         ),
          buildMode: buildMode,
          trackWidgetCreation: trackWidgetCreation,
          fileSystemRoots: fileSystemRoots,
@@ -66,8 +71,12 @@
     ResidentCompiler generator,
   }) async {
     ResidentCompiler generator;
+    final TargetPlatform targetPlatform = await device.targetPlatform;
+    if (device.platformType == PlatformType.fuchsia) {
+      targetModel = TargetModel.flutterRunner;
+    }
     if (featureFlags.isWebIncrementalCompilerEnabled &&
-        await device.targetPlatform == TargetPlatform.web_javascript) {
+        targetPlatform == TargetPlatform.web_javascript) {
       generator = ResidentCompiler(
         artifacts.getArtifactPath(Artifact.flutterWebSdk, mode: buildMode),
         buildMode: buildMode,
@@ -80,12 +89,17 @@
       );
     } else if (flutterProject.hasBuilders) {
       generator = await CodeGeneratingResidentCompiler.create(
+        targetPlatform: targetPlatform,
         buildMode: buildMode,
         flutterProject: flutterProject,
       );
     } else {
       generator = ResidentCompiler(
-        artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath, mode: buildMode),
+        artifacts.getArtifactPath(
+          Artifact.flutterPatchedSdkPath,
+          platform: targetPlatform,
+          mode: buildMode,
+        ),
         buildMode: buildMode,
         trackWidgetCreation: trackWidgetCreation,
         fileSystemRoots: fileSystemRoots,
@@ -102,6 +116,7 @@
       viewFilter: viewFilter,
       experimentalFlags: experimentalFlags,
       targetModel: targetModel,
+      targetPlatform: targetPlatform,
       generator: generator,
       buildMode: buildMode,
     );