[dart2wasm] Fix the case of an exported main.

Change-Id: Icf6b2b37a30b68f70c191394b6107e39dd060bde
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/250561
Reviewed-by: Aske Simon Christensen <askesc@google.com>
Commit-Queue: Joshua Litt <joshualitt@google.com>
diff --git a/pkg/dart2wasm/lib/translator.dart b/pkg/dart2wasm/lib/translator.dart
index c130f70..8e6c7d9 100644
--- a/pkg/dart2wasm/lib/translator.dart
+++ b/pkg/dart2wasm/lib/translator.dart
@@ -298,6 +298,28 @@
     };
   }
 
+  // Finds the `main` method for a given library which is assumed to contain
+  // `main`, either directly or indirectly.
+  Procedure _findMainMethod(Library entryLibrary) {
+    // First check to see if the library itself contains main.
+    for (final procedure in entryLibrary.procedures) {
+      if (procedure.name.text == 'main') {
+        return procedure;
+      }
+    }
+
+    // In some cases, a main method is defined in another file, and then
+    // exported. In these cases, we search for the main method in
+    // [additionalExports].
+    for (final export in entryLibrary.additionalExports) {
+      if (export.node is Procedure && export.asProcedure.name.text == 'main') {
+        return export.asProcedure;
+      }
+    }
+    throw ArgumentError(
+        'Entry uri ${entryLibrary.fileUri} has no main method.');
+  }
+
   Uint8List translate() {
     m = w.Module(watchPoints: options.watchPoints);
     voidMarker = w.RefType.def(w.StructType("void"), nullable: true);
@@ -305,8 +327,7 @@
     classInfoCollector.collect();
 
     functions.collectImportsAndExports();
-    mainFunction =
-        libraries.first.procedures.firstWhere((p) => p.name.text == "main");
+    mainFunction = _findMainMethod(libraries.first);
     functions.addExport(mainFunction.reference, "main");
 
     initFunction = m.addFunction(functionType(const [], const []), "#init");