From 97258979df13c5ea40490cd2615803f26ae6e507 Mon Sep 17 00:00:00 2001 From: gaaclarke <30870216+gaaclarke@users.noreply.github.com> Date: Mon, 21 Mar 2022 13:40:23 -0700 Subject: [PATCH] Revert "Starts using the `--source` flag to compile the dart registrant. (#98046) (#100493) --- .ci.yaml | 24 -- TESTOWNERS | 1 - .../bin/tasks/entrypoint_dart_registrant.dart | 12 - .../lib/tasks/entrypoint_dart_registrant.dart | 106 --------- .../targets/dart_plugin_registrant.dart | 4 +- packages/flutter_tools/lib/src/compile.dart | 50 ++-- .../lib/src/flutter_plugins.dart | 16 ++ packages/flutter_tools/lib/src/project.dart | 2 +- .../targets/dart_plugin_registrant_test.dart | 46 +++- .../general.shard/compile_batch_test.dart | 6 +- .../test/general.shard/dart_plugin_test.dart | 215 +++++++++++++++++- .../general.shard/resident_runner_test.dart | 8 +- .../resident_web_runner_test.dart | 8 +- .../test/test_compiler_test.dart | 8 +- 14 files changed, 303 insertions(+), 203 deletions(-) delete mode 100644 dev/devicelab/bin/tasks/entrypoint_dart_registrant.dart delete mode 100644 dev/devicelab/lib/tasks/entrypoint_dart_registrant.dart diff --git a/.ci.yaml b/.ci.yaml index 5d8ddd41d53b..fb35ead77e19 100755 --- a/.ci.yaml +++ b/.ci.yaml @@ -2628,30 +2628,6 @@ targets: - bin/** - .ci.yaml - - name: Mac entrypoint_dart_registrant - recipe: devicelab/devicelab_drone - bringup: true - timeout: 60 - properties: - caches: >- - [ - {"name":"gradle","path":"gradle"} - ] - dependencies: >- - [ - {"dependency": "xcode"}, - {"dependency": "gems"} - ] - tags: > - ["devicelab","hostonly"] - task_name: entrypoint_dart_registrant - scheduler: luci - runIf: - - dev/** - - packages/flutter_tools/** - - bin/** - - .ci.yaml - - name: Mac framework_tests_libraries recipe: flutter/flutter_drone timeout: 60 diff --git a/TESTOWNERS b/TESTOWNERS index 8439d8df70c1..72114a9776ec 100644 --- a/TESTOWNERS +++ b/TESTOWNERS @@ -200,7 +200,6 @@ /dev/devicelab/bin/tasks/gradle_plugin_light_apk_test.dart @stuartmorgan @flutter/plugin /dev/devicelab/bin/tasks/module_test_ios.dart @jmagman @flutter/tool /dev/devicelab/bin/tasks/plugin_lint_mac.dart @stuartmorgan @flutter/plugin -/dev/devicelab/bin/tasks/entrypoint_dart_registrant.dart @aaclarke @flutter/plugin /dev/devicelab/bin/tasks/windows_home_scroll_perf__timeline_summary.dart @jonahwilliams @flutter/engine ## Host only framework tests diff --git a/dev/devicelab/bin/tasks/entrypoint_dart_registrant.dart b/dev/devicelab/bin/tasks/entrypoint_dart_registrant.dart deleted file mode 100644 index b4e91beb4bef..000000000000 --- a/dev/devicelab/bin/tasks/entrypoint_dart_registrant.dart +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2014 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:flutter_devicelab/framework/devices.dart'; -import 'package:flutter_devicelab/framework/framework.dart'; -import 'package:flutter_devicelab/tasks/entrypoint_dart_registrant.dart'; - -Future main() async { - deviceOperatingSystem = DeviceOperatingSystem.android; - await task(entrypointDartRegistrant()); -} diff --git a/dev/devicelab/lib/tasks/entrypoint_dart_registrant.dart b/dev/devicelab/lib/tasks/entrypoint_dart_registrant.dart deleted file mode 100644 index a597b0f9c637..000000000000 --- a/dev/devicelab/lib/tasks/entrypoint_dart_registrant.dart +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2014 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'dart:async'; -import 'dart:convert'; -import 'dart:io' show Process, ProcessSignal, Directory, File; - -import '../framework/devices.dart'; -import '../framework/framework.dart'; -import '../framework/task_result.dart'; -import '../framework/utils.dart'; - -const String _messagePrefix = 'entrypoint:'; -const String _entrypointName = 'entrypoint'; - -const String _dartCode = ''' -import 'package:flutter/widgets.dart'; - -@pragma('vm:entry-point') -void main() { - print('$_messagePrefix main'); - runApp(const ColoredBox(color: Color(0xffcc0000))); -} - -@pragma('vm:entry-point') -void $_entrypointName() { - print('$_messagePrefix $_entrypointName'); - runApp(const ColoredBox(color: Color(0xff00cc00))); -} -'''; - -const String _kotlinCode = ''' -package com.example.entrypoint_dart_registrant - -import io.flutter.embedding.android.FlutterActivity - -class MainActivity: FlutterActivity() { - override fun getDartEntrypointFunctionName(): String { - return "$_entrypointName" - } -} -'''; - -Future _runWithTempDir(Directory tempDir) async { - const String testDirName = 'entrypoint_dart_registrant'; - final String testPath = '${tempDir.path}/$testDirName'; - await inDirectory(tempDir, () async { - await flutter('create', options: [ - '--platforms', - 'android', - testDirName, - ]); - }); - final String mainPath = '${tempDir.path}/$testDirName/lib/main.dart'; - print(mainPath); - File(mainPath).writeAsStringSync(_dartCode); - final String activityPath = - '${tempDir.path}/$testDirName/android/app/src/main/kotlin/com/example/entrypoint_dart_registrant/MainActivity.kt'; - File(activityPath).writeAsStringSync(_kotlinCode); - final Device device = await devices.workingDevice; - await device.unlock(); - final String entrypoint = await inDirectory(testPath, () async { - // The problem only manifested when the dart plugin registrant was used - // (which path_provider has). - await flutter('pub', options: ['add', 'path_provider:2.0.9']); - // The problem only manifested on release builds, so we test release. - final Process process = - await startFlutter('run', options: ['--release']); - final Completer completer = Completer(); - final StreamSubscription stdoutSub = process.stdout - .transform(const Utf8Decoder()) - .transform(const LineSplitter()) - .listen((String line) async { - print(line); - if (line.contains(_messagePrefix)) { - completer.complete(line); - } - }); - final String entrypoint = await completer.future; - await stdoutSub.cancel(); - process.stdin.write('q'); - await process.stdin.flush(); - process.kill(ProcessSignal.sigint); - return entrypoint; - }); - if (entrypoint.contains('$_messagePrefix $_entrypointName')) { - return TaskResult.success(null); - } else { - return TaskResult.failure('expected entrypoint:"$_entrypointName" but found:"$entrypoint"'); - } -} - -/// Asserts that the custom entrypoint works in the presence of the dart plugin -/// registrant. -TaskFunction entrypointDartRegistrant() { - return () async { - final Directory tempDir = - Directory.systemTemp.createTempSync('entrypoint_dart_registrant.'); - try { - return await _runWithTempDir(tempDir); - } finally { - rmTree(tempDir); - } - }; -} diff --git a/packages/flutter_tools/lib/src/build_system/targets/dart_plugin_registrant.dart b/packages/flutter_tools/lib/src/build_system/targets/dart_plugin_registrant.dart index e18e767854cb..c3054f6be6ed 100644 --- a/packages/flutter_tools/lib/src/build_system/targets/dart_plugin_registrant.dart +++ b/packages/flutter_tools/lib/src/build_system/targets/dart_plugin_registrant.dart @@ -12,7 +12,7 @@ import '../../flutter_plugins.dart'; import '../../project.dart'; import '../build_system.dart'; -/// Generates a new `./dart_tool/flutter_build/dart_plugin_registrant.dart` +/// Generates a new `./dart_tool/flutter_build/generated_main.dart` /// based on the current dependency map in `pubspec.lock`. class DartPluginRegistrantTarget extends Target { /// Construct a [DartPluginRegistrantTarget]. @@ -86,7 +86,7 @@ class DartPluginRegistrantTarget extends Target { @override List get outputs => [ const Source.pattern( - '{PROJECT_DIR}/.dart_tool/flutter_build/dart_plugin_registrant.dart', + '{PROJECT_DIR}/.dart_tool/flutter_build/generated_main.dart', optional: true, ), ]; diff --git a/packages/flutter_tools/lib/src/compile.dart b/packages/flutter_tools/lib/src/compile.dart index 588c35f2d9dd..5eed616f5ef1 100644 --- a/packages/flutter_tools/lib/src/compile.dart +++ b/packages/flutter_tools/lib/src/compile.dart @@ -261,12 +261,14 @@ class KernelCompiler { if (outputFilePath != null && !_fileSystem.isFileSync(outputFilePath)) { _fileSystem.file(outputFilePath).createSync(recursive: true); } - - // Check if there's a Dart plugin registrant. - // This is contained in the file `dart_plugin_registrant.dart` under `.dart_tools/flutter_build/`. - final File? dartPluginRegistrant = checkDartPluginRegistry - ? buildDir?.parent.childFile('dart_plugin_registrant.dart') - : null; + if (buildDir != null && checkDartPluginRegistry) { + // Check if there's a Dart plugin registrant. + // This is contained in the file `generated_main.dart` under `.dart_tools/flutter_build/`. + final File newMainDart = buildDir.parent.childFile('generated_main.dart'); + if (newMainDart.existsSync()) { + mainUri = newMainDart.path; + } + } final List command = [ engineDartPath, @@ -314,10 +316,6 @@ class KernelCompiler { '--platform', platformDill, ], - if (dartPluginRegistrant != null && dartPluginRegistrant.existsSync()) ...[ - '--source', - dartPluginRegistrant.path, - ], ...?extraFrontEndOptions, mainUri, ]; @@ -361,7 +359,6 @@ class _RecompileRequest extends _CompilationRequest { this.outputPath, this.packageConfig, this.suppressErrors, - {this.additionalSource} ) : super(completer); Uri mainUri; @@ -369,7 +366,6 @@ class _RecompileRequest extends _CompilationRequest { String outputPath; PackageConfig packageConfig; bool suppressErrors; - final String? additionalSource; @override Future _run(DefaultResidentCompiler compiler) async => @@ -635,31 +631,24 @@ class DefaultResidentCompiler implements ResidentCompiler { if (!_controller.hasListener) { _controller.stream.listen(_handleCompilationRequest); } - String? additionalSource; - // `dart_plugin_registrant.dart` contains the Dart plugin registry. + // `generated_main.dart` contains the Dart plugin registry. if (checkDartPluginRegistry && projectRootPath != null && fs != null) { - final File dartPluginRegistrantDart = fs.file( + final File generatedMainDart = fs.file( fs.path.join( projectRootPath, '.dart_tool', 'flutter_build', - 'dart_plugin_registrant.dart', + 'generated_main.dart', ), ); - if (dartPluginRegistrantDart != null && dartPluginRegistrantDart.existsSync()) { - additionalSource = dartPluginRegistrantDart.path; + if (generatedMainDart != null && generatedMainDart.existsSync()) { + mainUri = generatedMainDart.uri; } } final Completer completer = Completer(); - _controller.add(_RecompileRequest( - completer, - mainUri, - invalidatedFiles, - outputPath, - packageConfig, - suppressErrors, - additionalSource: additionalSource, - )); + _controller.add( + _RecompileRequest(completer, mainUri, invalidatedFiles, outputPath, packageConfig, suppressErrors) + ); return completer.future; } @@ -673,7 +662,7 @@ class DefaultResidentCompiler implements ResidentCompiler { final Process? server = _server; if (server == null) { - return _compile(mainUri, request.outputPath, additionalSource: request.additionalSource); + return _compile(mainUri, request.outputPath); } final String inputKey = Uuid().generateV4(); @@ -719,7 +708,6 @@ class DefaultResidentCompiler implements ResidentCompiler { Future _compile( String scriptUri, String? outputPath, - {String? additionalSource} ) async { final String frontendServer = _artifacts.getArtifactPath( Artifact.frontendServerSnapshotForEngineDartSdk @@ -772,10 +760,6 @@ class DefaultResidentCompiler implements ResidentCompiler { initializeFromDill!, ], if (assumeInitializeFromDillUpToDate) '--assume-initialize-from-dill-up-to-date', - if (additionalSource != null) ...[ - '--source', - additionalSource, - ], if (platformDill != null) ...[ '--platform', platformDill!, diff --git a/packages/flutter_tools/lib/src/flutter_plugins.dart b/packages/flutter_tools/lib/src/flutter_plugins.dart index d6a7e088f205..f9d949d7a1f2 100644 --- a/packages/flutter_tools/lib/src/flutter_plugins.dart +++ b/packages/flutter_tools/lib/src/flutter_plugins.dart @@ -706,6 +706,10 @@ const String _dartPluginRegistryForNonWebTemplate = ''' // @dart = {{dartLanguageVersion}} +// When `{{mainEntrypoint}}` defines `main`, that definition is shadowed by the definition below. +export '{{mainEntrypoint}}'; + +import '{{mainEntrypoint}}' as entrypoint; import 'dart:io'; // flutter_ignore: dart_io_import. {{#android}} import 'package:{{pluginName}}/{{pluginName}}.dart'; @@ -750,6 +754,18 @@ $_dartPluginRegisterWith {{/windows}} } } + +} + +typedef _UnaryFunction = dynamic Function(List args); +typedef _NullaryFunction = dynamic Function(); + +void main(List args) { + if (entrypoint.main is _UnaryFunction) { + (entrypoint.main as _UnaryFunction)(args); + } else { + (entrypoint.main as _NullaryFunction)(); + } } '''; diff --git a/packages/flutter_tools/lib/src/project.dart b/packages/flutter_tools/lib/src/project.dart index d56afe6270ad..ef2710e45caa 100644 --- a/packages/flutter_tools/lib/src/project.dart +++ b/packages/flutter_tools/lib/src/project.dart @@ -236,7 +236,7 @@ class FlutterProject { /// The generated Dart plugin registrant for non-web platforms. File get dartPluginRegistrant => dartTool .childDirectory('flutter_build') - .childFile('dart_plugin_registrant.dart'); + .childFile('generated_main.dart'); /// The example sub-project of this project. FlutterProject get example => FlutterProject( diff --git a/packages/flutter_tools/test/general.shard/build_system/targets/dart_plugin_registrant_test.dart b/packages/flutter_tools/test/general.shard/build_system/targets/dart_plugin_registrant_test.dart index 6b97b1ed411b..64c628ded742 100644 --- a/packages/flutter_tools/test/general.shard/build_system/targets/dart_plugin_registrant_test.dart +++ b/packages/flutter_tools/test/general.shard/build_system/targets/dart_plugin_registrant_test.dart @@ -159,7 +159,7 @@ void main() { } }); - testUsingContext("doesn't generate dart_plugin_registrant.dart if there aren't Dart plugins", () async { + testUsingContext("doesn't generate generated_main.dart if there aren't Dart plugins", () async { final Directory projectDir = fileSystem.directory('project')..createSync(); final Environment environment = Environment.test( fileSystem.currentDirectory, @@ -189,11 +189,11 @@ void main() { final File generatedMain = projectDir .childDirectory('.dart_tool') .childDirectory('flutter_build') - .childFile('dart_plugin_registrant.dart'); + .childFile('generated_main.dart'); expect(generatedMain.existsSync(), isFalse); }); - testUsingContext('regenerates dart_plugin_registrant.dart', () async { + testUsingContext('regenerates generated_main.dart', () async { final Directory projectDir = fileSystem.directory('project')..createSync(); final Environment environment = Environment.test( fileSystem.currentDirectory, @@ -231,7 +231,7 @@ void main() { final File generatedMain = projectDir .childDirectory('.dart_tool') .childDirectory('flutter_build') - .childFile('dart_plugin_registrant.dart'); + .childFile('generated_main.dart'); final String mainContent = generatedMain.readAsStringSync(); expect( mainContent, @@ -243,6 +243,10 @@ void main() { '\n' '// @dart = 2.12\n' '\n' + '// When `package:path_provider_example/main.dart` defines `main`, that definition is shadowed by the definition below.\n' + "export 'package:path_provider_example/main.dart';\n" + '\n' + "import 'package:path_provider_example/main.dart' as entrypoint;\n" "import 'dart:io'; // flutter_ignore: dart_io_import.\n" "import 'package:path_provider_linux/path_provider_linux.dart';\n" '\n' @@ -268,12 +272,24 @@ void main() { ' } else if (Platform.isWindows) {\n' ' }\n' ' }\n' + '\n' + '}\n' + '\n' + 'typedef _UnaryFunction = dynamic Function(List args);\n' + 'typedef _NullaryFunction = dynamic Function();\n' + '\n' + 'void main(List args) {\n' + ' if (entrypoint.main is _UnaryFunction) {\n' + ' (entrypoint.main as _UnaryFunction)(args);\n' + ' } else {\n' + ' (entrypoint.main as _NullaryFunction)();\n' + ' }\n' '}\n' ), ); }); - testUsingContext('removes dart_plugin_registrant.dart if plugins are removed from pubspec.yaml', () async { + testUsingContext('removes generated_main.dart if plugins are removed from pubspec.yaml', () async { final Directory projectDir = fileSystem.directory('project')..createSync(); final Environment environment = Environment.test( fileSystem.currentDirectory, @@ -305,7 +321,7 @@ void main() { final File generatedMain = projectDir .childDirectory('.dart_tool') .childDirectory('flutter_build') - .childFile('dart_plugin_registrant.dart'); + .childFile('generated_main.dart'); final FlutterProject testProject = FlutterProject.fromDirectoryTest(projectDir); await DartPluginRegistrantTarget.test(testProject).build(environment); @@ -356,7 +372,7 @@ void main() { final File generatedMain = projectDir .childDirectory('.dart_tool') .childDirectory('flutter_build') - .childFile('dart_plugin_registrant.dart'); + .childFile('generated_main.dart'); final String mainContent = generatedMain.readAsStringSync(); expect( @@ -369,6 +385,10 @@ void main() { '\n' '// @dart = 2.12\n' '\n' + '// When `file:///root/external.dart` defines `main`, that definition is shadowed by the definition below.\n' + "export 'file:///root/external.dart';\n" + '\n' + "import 'file:///root/external.dart' as entrypoint;\n" "import 'dart:io'; // flutter_ignore: dart_io_import.\n" "import 'package:path_provider_linux/path_provider_linux.dart';\n" '\n' @@ -394,6 +414,18 @@ void main() { ' } else if (Platform.isWindows) {\n' ' }\n' ' }\n' + '\n' + '}\n' + '\n' + 'typedef _UnaryFunction = dynamic Function(List args);\n' + 'typedef _NullaryFunction = dynamic Function();\n' + '\n' + 'void main(List args) {\n' + ' if (entrypoint.main is _UnaryFunction) {\n' + ' (entrypoint.main as _UnaryFunction)(args);\n' + ' } else {\n' + ' (entrypoint.main as _NullaryFunction)();\n' + ' }\n' '}\n' ), ); diff --git a/packages/flutter_tools/test/general.shard/compile_batch_test.dart b/packages/flutter_tools/test/general.shard/compile_batch_test.dart index 519dd11993a5..627db081fa36 100644 --- a/packages/flutter_tools/test/general.shard/compile_batch_test.dart +++ b/packages/flutter_tools/test/general.shard/compile_batch_test.dart @@ -395,9 +395,7 @@ void main() { '--no-link-platform', '--packages', '.packages', - '--source', - '.dart_tools/flutter_build/dart_plugin_registrant.dart', - 'scheme:///main.dart', + '.dart_tools/flutter_build/generated_main.dart', ], completer: completer), ]), stdoutHandler: stdoutHandler, @@ -407,7 +405,7 @@ void main() { .childDirectory('flutter_build') .childDirectory('test'); - buildDir.parent.childFile('dart_plugin_registrant.dart').createSync(recursive: true); + buildDir.parent.childFile('generated_main.dart').createSync(recursive: true); final Future output = kernelCompiler.compile(sdkRoot: '/path/to/sdkroot', mainPath: '/foo/bar/fizz/main.dart', diff --git a/packages/flutter_tools/test/general.shard/dart_plugin_test.dart b/packages/flutter_tools/test/general.shard/dart_plugin_test.dart index 5cbea5fc0b92..2a7364f7bbcc 100644 --- a/packages/flutter_tools/test/general.shard/dart_plugin_test.dart +++ b/packages/flutter_tools/test/general.shard/dart_plugin_test.dart @@ -35,7 +35,7 @@ void main() { ..directory = directory ..flutterPluginsFile = directory.childFile('.flutter-plugins') ..flutterPluginsDependenciesFile = directory.childFile('.flutter-plugins-dependencies') - ..dartPluginRegistrant = directory.childFile('dart_plugin_registrant.dart'); + ..dartPluginRegistrant = directory.childFile('generated_main.dart'); flutterProject.directory.childFile('.packages').createSync(recursive: true); }); @@ -701,6 +701,206 @@ void main() { '\n' '// @dart = 2.8\n' '\n' + '// When `package:app/main.dart` defines `main`, that definition is shadowed by the definition below.\n' + "export 'package:app/main.dart';\n" + '\n' + "import 'package:app/main.dart' as entrypoint;\n" + "import 'dart:io'; // flutter_ignore: dart_io_import.\n" + "import 'package:url_launcher_android/url_launcher_android.dart';\n" + "import 'package:url_launcher_ios/url_launcher_ios.dart';\n" + "import 'package:url_launcher_linux/url_launcher_linux.dart';\n" + "import 'package:awesome_macos/awesome_macos.dart';\n" + "import 'package:url_launcher_macos/url_launcher_macos.dart';\n" + "import 'package:url_launcher_windows/url_launcher_windows.dart';\n" + '\n' + "@pragma('vm:entry-point')\n" + 'class _PluginRegistrant {\n' + '\n' + " @pragma('vm:entry-point')\n" + ' static void register() {\n' + ' if (Platform.isAndroid) {\n' + ' try {\n' + ' AndroidPlugin.registerWith();\n' + ' } catch (err) {\n' + ' print(\n' + " '`url_launcher_android` threw an error: \$err. '\n" + " 'The app may not function as expected until you remove this plugin from pubspec.yaml'\n" + ' );\n' + ' rethrow;\n' + ' }\n' + '\n' + ' } else if (Platform.isIOS) {\n' + ' try {\n' + ' IosPlugin.registerWith();\n' + ' } catch (err) {\n' + ' print(\n' + " '`url_launcher_ios` threw an error: \$err. '\n" + " 'The app may not function as expected until you remove this plugin from pubspec.yaml'\n" + ' );\n' + ' rethrow;\n' + ' }\n' + '\n' + ' } else if (Platform.isLinux) {\n' + ' try {\n' + ' LinuxPlugin.registerWith();\n' + ' } catch (err) {\n' + ' print(\n' + " '`url_launcher_linux` threw an error: \$err. '\n" + " 'The app may not function as expected until you remove this plugin from pubspec.yaml'\n" + ' );\n' + ' rethrow;\n' + ' }\n' + '\n' + ' } else if (Platform.isMacOS) {\n' + ' try {\n' + ' AwesomeMacOS.registerWith();\n' + ' } catch (err) {\n' + ' print(\n' + " '`awesome_macos` threw an error: \$err. '\n" + " 'The app may not function as expected until you remove this plugin from pubspec.yaml'\n" + ' );\n' + ' rethrow;\n' + ' }\n' + '\n' + ' try {\n' + ' MacOSPlugin.registerWith();\n' + ' } catch (err) {\n' + ' print(\n' + " '`url_launcher_macos` threw an error: \$err. '\n" + " 'The app may not function as expected until you remove this plugin from pubspec.yaml'\n" + ' );\n' + ' rethrow;\n' + ' }\n' + '\n' + ' } else if (Platform.isWindows) {\n' + ' try {\n' + ' WindowsPlugin.registerWith();\n' + ' } catch (err) {\n' + ' print(\n' + " '`url_launcher_windows` threw an error: \$err. '\n" + " 'The app may not function as expected until you remove this plugin from pubspec.yaml'\n" + ' );\n' + ' rethrow;\n' + ' }\n' + '\n' + ' }\n' + ' }\n' + '\n' + '}\n' + '\n' + 'typedef _UnaryFunction = dynamic Function(List args);\n' + 'typedef _NullaryFunction = dynamic Function();\n' + '\n' + 'void main(List args) {\n' + ' if (entrypoint.main is _UnaryFunction) {\n' + ' (entrypoint.main as _UnaryFunction)(args);\n' + ' } else {\n' + ' (entrypoint.main as _NullaryFunction)();\n' + ' }\n' + '}\n', + ); + }, overrides: { + FileSystem: () => fs, + ProcessManager: () => FakeProcessManager.any(), + }); + + testUsingContext('Rewires entrypoints', () async { + flutterProject.isModule = true; + + createFakeDartPlugins( + flutterProject, + flutterManifest, + fs, + { + 'url_launcher_android': ''' + flutter: + plugin: + implements: url_launcher + platforms: + android: + dartPluginClass: AndroidPlugin +''', + 'url_launcher_ios': ''' + flutter: + plugin: + implements: url_launcher + platforms: + ios: + dartPluginClass: IosPlugin +''', + 'url_launcher_macos': ''' + flutter: + plugin: + implements: url_launcher + platforms: + macos: + dartPluginClass: MacOSPlugin +''', + 'url_launcher_linux': ''' + flutter: + plugin: + implements: url_launcher + platforms: + linux: + dartPluginClass: LinuxPlugin +''', + 'url_launcher_windows': ''' + flutter: + plugin: + implements: url_launcher + platforms: + windows: + dartPluginClass: WindowsPlugin +''', + 'awesome_macos': ''' + flutter: + plugin: + implements: awesome + platforms: + macos: + dartPluginClass: AwesomeMacOS +''' + }); + + final Directory libDir = flutterProject.directory.childDirectory('lib'); + libDir.createSync(recursive: true); + + final File mainFile = libDir.childFile('main.dart'); + mainFile.writeAsStringSync(''' +// @dart = 2.8 +void main() { +} + +@pragma('vm:entry-point') +void dream() => run(interactive: false); + +@pragma('vm:entry-point', foobar) +void dreamWithFlags() => run(interactive: false); +'''); + final PackageConfig packageConfig = await loadPackageConfigWithLogging( + flutterProject.directory.childDirectory('.dart_tool').childFile('package_config.json'), + logger: globals.logger, + throwOnError: false, + ); + await generateMainDartWithPluginRegistrant( + flutterProject, + packageConfig, + 'package:app/main.dart', + mainFile, + throwOnPluginPubspecError: true, + ); + expect(flutterProject.dartPluginRegistrant.readAsStringSync(), + '//\n' + '// Generated file. Do not edit.\n' + '// This file is generated from template in file `flutter_tools/lib/src/flutter_plugins.dart`.\n' + '//\n' + '\n' + '// @dart = 2.8\n' + '\n' + '// When `package:app/main.dart` defines `main`, that definition is shadowed by the definition below.\n' + "export 'package:app/main.dart';\n" + '\n' + "import 'package:app/main.dart' as entrypoint;\n" "import 'dart:io'; // flutter_ignore: dart_io_import.\n" "import 'package:url_launcher_android/url_launcher_android.dart';\n" "import 'package:url_launcher_ios/url_launcher_ios.dart';\n" @@ -781,7 +981,20 @@ void main() { '\n' ' }\n' ' }\n' + '\n' + '}\n' + '\n' + 'typedef _UnaryFunction = dynamic Function(List args);\n' + 'typedef _NullaryFunction = dynamic Function();\n' + '\n' + 'void main(List args) {\n' + ' if (entrypoint.main is _UnaryFunction) {\n' + ' (entrypoint.main as _UnaryFunction)(args);\n' + ' } else {\n' + ' (entrypoint.main as _NullaryFunction)();\n' + ' }\n' '}\n' + , ); }, overrides: { FileSystem: () => fs, diff --git a/packages/flutter_tools/test/general.shard/resident_runner_test.dart b/packages/flutter_tools/test/general.shard/resident_runner_test.dart index feb7ff42f7d0..dd8f031dbe62 100644 --- a/packages/flutter_tools/test/general.shard/resident_runner_test.dart +++ b/packages/flutter_tools/test/general.shard/resident_runner_test.dart @@ -1189,8 +1189,8 @@ void main() { ] } '''); - // Start from an empty dart_plugin_registrant.dart file. - globals.fs.directory('.dart_tool').childDirectory('flutter_build').childFile('dart_plugin_registrant.dart').createSync(recursive: true); + // Start from an empty generated_main.dart file. + globals.fs.directory('.dart_tool').childDirectory('flutter_build').childFile('generated_main.dart').createSync(recursive: true); await residentRunner.runSourceGenerators(); @@ -1267,9 +1267,9 @@ flutter: final File generatedMain = globals.fs.directory('.dart_tool') .childDirectory('flutter_build') - .childFile('dart_plugin_registrant.dart'); + .childFile('generated_main.dart'); - expect(generatedMain.existsSync(), isTrue); + expect(generatedMain.readAsStringSync(), contains('custom_main.dart')); expect(testLogger.errorText, isEmpty); expect(testLogger.statusText, isEmpty); })); diff --git a/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart b/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart index 1e553d661f34..d1bcdf5c5e88 100644 --- a/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart +++ b/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart @@ -936,7 +936,7 @@ void main() { // While this file should be ignored on web, generating it here will cause a // perf regression in hot restart. - testUsingContext('Does not generate dart_plugin_registrant.dart', () async { + testUsingContext('Does not generate generated_main.dart', () async { // Create necessary files for [DartPluginRegistrantTarget] final File packageConfig = globals.fs.directory('.dart_tool') .childFile('package_config.json'); @@ -954,10 +954,10 @@ void main() { ] } '''); - // Start with a dart_plugin_registrant.dart file. + // Start with a generated_main.dart file. globals.fs.directory('.dart_tool') .childDirectory('flutter_build') - .childFile('dart_plugin_registrant.dart') + .childFile('generated_main.dart') .createSync(recursive: true); final FlutterProject project = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory); @@ -965,7 +965,7 @@ void main() { final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice); await residentWebRunner.runSourceGenerators(); - // dart_plugin_registrant.dart should be untouched, indicating that its + // generated_main.dart should be untouched, indicating that its // generation didn't run. If it had run, the file would have been removed as // there are no plugins in the project. expect(project.dartPluginRegistrant.existsSync(), true); diff --git a/packages/flutter_tools/test/general.shard/test/test_compiler_test.dart b/packages/flutter_tools/test/general.shard/test/test_compiler_test.dart index 415e87795f4a..f2eced899468 100644 --- a/packages/flutter_tools/test/general.shard/test/test_compiler_test.dart +++ b/packages/flutter_tools/test/general.shard/test/test_compiler_test.dart @@ -115,7 +115,7 @@ void main() { Logger: () => BufferLogger.test(), }); - testUsingContext('TestCompiler updates dart_plugin_registrant.dart', () async { + testUsingContext('TestCompiler updates generated_main.dart', () async { final Directory fakeDartPlugin = fileSystem.directory('a_plugin'); fileSystem.file('pubspec.yaml').writeAsStringSync(''' name: foo @@ -152,12 +152,12 @@ environment: final File generatedMain = fileSystem .directory('.dart_tool') .childDirectory('flutter_build') - .childFile('dart_plugin_registrant.dart'); + .childFile('generated_main.dart'); expect(generatedMain, exists); expect( - generatedMain.readAsStringSync(), - contains('APlugin.registerWith();') + generatedMain.readAsLinesSync(), + contains("import 'test/foo.dart' as entrypoint;") ); }, overrides: { FileSystem: () => fileSystem,