Repository navigation
dartPluginClass forces to export implementation of platform interface as public api #152833
Description
Use case
Wasn't sure about type of Issue here, but decided to do "Feature Request" since I believe it can be new functionality based on source code from Flutter, which I'll provide later.
Question is about usage of dartPluginClass for providing dart-only implementations for Flutter plugins.
At the moment, when platform-specific implementation is provided with dartPluginClass, this implementation has to be exported as Public API. It is obligatory, as far as I understand, because it is not possible to set fileName (as for web implementation) with dartPluginClass. My observation based on source-code of dart_plugin_registrant.dart template which doesn't allow other imports than 'package:{{pluginName}}/{{pluginName}}.dart'
If implementation classes are not exported, build will brake on all platforms, except for web, because web has it's own mechanism.
Build error will look like this (this stack trace is from example repo for reproduction, I will provide link in the end.):
Launching lib/main.dart on macOS in debug mode...
--- xcodebuild: WARNING: Using the first of multiple matching destinations:
{ platform:macOS, arch:arm64, id:00006000-000849E41162801E, name:My Mac }
{ platform:macOS, arch:x86_64, id:00006000-000849E41162801E, name:My Mac }
.dart_tool/flutter_build/dart_plugin_registrant.dart:22:9: Error: Undefined name 'DartCounterImpl'.
DartCounterImpl.registerWith();
^^^^^^^^^^^^^^^
.dart_tool/flutter_build/dart_plugin_registrant.dart:32:9: Error: Undefined name 'DartCounterImpl'.
DartCounterImpl.registerWith();
^^^^^^^^^^^^^^^
.dart_tool/flutter_build/dart_plugin_registrant.dart:42:9: Error: Undefined name 'DartCounterImpl'.
DartCounterImpl.registerWith();
^^^^^^^^^^^^^^^
.dart_tool/flutter_build/dart_plugin_registrant.dart:52:9: Error: Undefined name 'DartCounterImpl'.
DartCounterImpl.registerWith();
^^^^^^^^^^^^^^^
.dart_tool/flutter_build/dart_plugin_registrant.dart:62:9: Error: Undefined name 'DartCounterImpl'.
DartCounterImpl.registerWith();
^^^^^^^^^^^^^^^
Target kernel_snapshot_program failed: Exception
Command PhaseScriptExecution failed with a nonzero exit code
** BUILD FAILED **
Steps to reproduce:
- Use sample project from here: https://github.com/Sameri11/dart_plugin_class_example_error
- Take a look at
lib/dart_plugin_class_sample.dart: there is big comment about issue. - Comment or delete this line (26)
- Go to
example - Run
flutter runfor any platform other thanweb - See exception from above
- Optionally: if your revert step 3 (deleting line) – build will work
Real life example
I discovered this behaviour contributing to flutter_file_picker here. Not asking to look at that PR, but it can provide a little more context, if someone wants to dive in. TL:DR – this PR could benefit if exporting implementations wasn't obligatory.
Flutter doctor -v
[✓] Flutter (Channel master, 3.24.0-1.0.pre.411, on macOS 14.3.1 23D60 darwin-arm64, locale en-RU)
• Flutter version 3.24.0-1.0.pre.411 on channel master at /Users/samer/fvm/versions/master
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision a1a3b2ce3c (2 days ago), 2024-08-02 06:09:24 -0400
• Engine revision b408111b97
• Dart version 3.6.0 (build 3.6.0-108.0.dev)
• DevTools version 2.38.0
[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
• Android SDK at /Users/samer/Library/Android/sdk
• Platform android-35, build-tools 34.0.0
• Java binary at: /Users/samer/Applications/Android Studio Koala
2024.1.1.app/Contents/jbr/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 17.0.10+0-17.0.10b1087.21-11609105)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 15.3)
• Xcode at /Applications/Xcode-15.3.app/Contents/Developer
• Build 15E204a
• CocoaPods version 1.15.2
[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Android Studio (version 2024.1)
• Android Studio at /Users/samer/Applications/Android Studio Koala 2024.1.1.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 17.0.10+0-17.0.10b1087.21-11609105)
[!] Android Studio (version unknown)
• Android Studio at /Users/samer/Applications/Android Studio Koala Feature Drop 2024.1.2 Canary
5.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
✗ Unable to determine Android Studio version.
• Java version OpenJDK Runtime Environment (build 17.0.11+0-17.0.11b1207.24-11852314)
[✓] Android Studio (version 2024.1)
• Android Studio at /Users/samer/Applications/Android Studio.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 17.0.10+0-17.0.10b1087.21-11609105)
[✓] IntelliJ IDEA Ultimate Edition (version EAP IU-242.20224.38)
• IntelliJ at /Users/samer/Applications/IntelliJ IDEA Ultimate.app
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
[✓] VS Code (version 1.91.1)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.94.0
[✓] Connected device (6 available)
• sdk gphone64 arm64 (mobile) • emulator-5554 • android-arm64 •
Android 15 (API 35) (emulator)
• iPhone (Михаил) (mobile) • 00008020-001254DA1E39002E • ios • iOS
17.5.1 21F90
• iPhone 15 (mobile) • 9AD45704-B570-4B87-902F-233C3F7F2280 • ios •
com.apple.CoreSimulator.SimRuntime.iOS-17-4 (simulator)
• macOS (desktop) • macos • darwin-arm64 •
macOS 14.3.1 23D60 darwin-arm64
• Mac Designed for iPad (desktop) • mac-designed-for-ipad • darwin •
macOS 14.3.1 23D60 darwin-arm64
• Chrome (web) • chrome • web-javascript •
Google Chrome 126.0.6478.185
[✓] Network resources
• All expected network resources are available.
! Doctor found issues in 1 category.
Proposal
Provide some possibility not to export implementation classes when using dartPluginClass. I'm not expert here, but obvious option from my perspective is to respect fileName field in pubspec.yaml, as web already does.
Activity
stuartmorgan-g commentedon Aug 4, 2024
Based on the PR it appears that the use case is having an implementation class whose file imports things that web build can't import; with a
dartFileNameplugin implementations could avoid having to do a layer of conditional imports. This came up in 1P plugin development at some point, so it's possible this is a duplicate of an existing issue, but I can't find it at the moment so maybe we didn't file it.(That use case is a bit fragile since it relies on web and non-web having completely different registrant codepaths in the tool, which ideally we would someday fix, but it may well be that that's an assumption that's so baked into the web side of the ecosystem at this point that we can't fully unify them.)
Sameri11 commentedon Aug 4, 2024
That's true, thank you! But also, I believe that described approach (not to export implementations) is "generally" better because it provides a little more flexibility for constructing public API: unnecessary private details stays private.
That said, I'm curious if proposal I outlined in the end of issue is appropriate? If so, I might try to give it a shot and try to implement.
stuartmorgan-g commentedon Aug 4, 2024
Given that
dartPluginClassis generally implementing the platform interface, which must be public in order for the plugin to be federated in the first place, it's not clear to me what real use cases there are beyond the web/non-web library support issue. Anyone with actual use cases is certainly welcome to post details.Adding a
dartFileNameto the platforms that supportdartPluginClassis reasonable. IIRC we considered it initially and didn't only because we weren't aware of a use case at the time.Sameri11 commentedon Aug 11, 2024
I created PR on this matter, and it is ready for review! Would be happy to discuss implementation there.
[tool] Add `dartFileName` setting for platform plugins (#153099)
github-actions commentedon Sep 20, 2024
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of
flutter doctor -vand a minimal reproduction of the issue.