-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Description
The dart language team will soon be changing the behavior of the language so that an invocation of a private class members won't get dispatched to a noSuchMethod method in another library; instead an exception will be thrown. This is a necessary prerequisite to allowing promotion of private fields (dart-lang/language#2020). It also closes an important privacy loophole in the language, by ensuring that the user can see all the possible behaviors of a private member invocation without having to look outside of the library.
This has an important consequence for PlatformInterface (from the plugin_platform_interface package), which insists that it be subclassed by clients via extends rather than implements, and detects the difference by reading from the private field _instanceToken and checking whether the expected value was returned. Today, that technique works some of the time (it relies on the implementing class having an implementation of noSuchMethod that completes without throwing an exception), but after the upcoming language change it will always throw a yet-to-be-defined exception.
I believe we should change PlatformInterface._instanceToken to use an expando (similar to what was done in #109238), so that PlatformInterface will be able to reliably detect whether it is subclassed by extends or implements, both before and after the upcoming language change.
In the process we'll also need to update several brittle tests that rely on the invocation of _instanceToken being dispatched to the standard Object.noSuchMethod method, and thus expect a NoSuchMethodError to be thrown. Changing PlatformInterface._instanceToken to use an expando will prevent the NoSuchMethodError from occurring, and instead PlatformInterface._verify will throw an AssertionError. These tests need to be updated so that they don't care what particular kind of exception is thrown. The tests I've found that require fixing are in the following repos:
- https://github.com/firebase/flutterfire
- https://github.com/Baseflow/flutter-geocoding
- https://github.com/Baseflow/flutter-geolocator
- https://github.com/Lyokone/flutterlocation
- https://github.com/flutter/plugins
To avoid breakages, I'll submit PRs to these repos before landing the change to PlatformInterface.