Skip to content

dartPluginClass forces to export implementation of platform interface as public api #152833

Closed

Description

@Sameri11

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:

  1. Use sample project from here: https://github.com/Sameri11/dart_plugin_class_example_error
  2. Take a look at lib/dart_plugin_class_sample.dart: there is big comment about issue.
  3. Comment or delete this line (26)
  4. Go to example
  5. Run flutter run for any platform other than web
  6. See exception from above
  7. 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

  1. added
    toolAffects the "flutter" command-line tool. See also t: labels.
    a: pluginsSupport for writing, building, and running plugin packages
    on Aug 4, 2024
  2. stuartmorgan-g commented on Aug 4, 2024

    @stuartmorgan-g
    Contributor

    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 dartFileName plugin 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.)

  3. Sameri11 commented on Aug 4, 2024

    @Sameri11
    ContributorAuthor

    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

    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.

  4. stuartmorgan-g commented on Aug 4, 2024

    @stuartmorgan-g
    Contributor

    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.

    Given that dartPluginClass is 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.

    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.

    Adding a dartFileName to the platforms that support dartPluginClass is reasonable. IIRC we considered it initially and didn't only because we weren't aware of a use case at the time.

  5. added
    P2Important issues not at the top of the work list
    on Aug 6, 2024
  6. Sameri11 commented on Aug 11, 2024

    @Sameri11
    ContributorAuthor

    I created PR on this matter, and it is ready for review! Would be happy to discuss implementation there.

  7. added a commit that references this issue on Sep 6, 2024
    d932115
  8. github-actions commented on Sep 20, 2024

    @github-actions

    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 -v and a minimal reproduction of the issue.

  9. locked as resolved and limited conversation to collaborators on Sep 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work lista: pluginsSupport for writing, building, and running plugin packagesteam-ecosystemOwned by Ecosystem teamtoolAffects the "flutter" command-line tool. See also t: labels.triaged-ecosystemTriaged by Ecosystem team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions