Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Conversation

@stereotype441
Copy link
Contributor

@stereotype441 stereotype441 commented Sep 12, 2022

This change replaces PlatformInterface._instanceToken (an instance field that points from a PlatformInterface to its corresponding token) with an expando that maps from PlatformInterface to Object. There is no change to the public API, and no change to the behavior of users' production code.

This change ensures that if a customer tries to implement PlatformInterface using implements rather than extends, the code in PlatformInterface._verify won't try to access the private _instanceToken field in PlatformInterface. This is important because an upcoming change to the dart language is going to cause such accesses to throw exceptions rather than deferring to noSuchMethod (see dart-lang/language#2020 for details).

Fixes flutter/flutter#109339.

Pre-launch Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read and followed the relevant style guides and ran the auto-formatter. (Unlike the flutter/flutter repo, the flutter/plugins repo does use dart format.)
  • I signed the CLA.
  • The title of the PR starts with the name of the plugin surrounded by square brackets, e.g. [shared_preferences]
  • I listed at least one issue that this PR fixes in the description above.
  • I updated pubspec.yaml with an appropriate new version according to the pub versioning philosophy, or this PR is exempt from version changes.
  • I updated CHANGELOG.md to add a description of the change, following repository CHANGELOG style.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is test-exempt.
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

This change replaces `PlatformInterface._instanceToken` (an instance
field that points from a `PlatformInterface` to its corresponding
token) with an expando that maps from `PlatformInterface` to `Object`.
There is no change to the public API, and no change to the behavior of
users' production code.

This change ensures that if a customer tries to implement
`PlatformInterface` using `implements` rather than `extends`, the code
in `PlatformInterface._verify` won't try to access the private
`_instanceToken` field in `PlatformInterface`.  This is important
because an upcoming change to the dart language is going to cause such
accesses to throw exceptions rather than deferring to `noSuchMethod`
(see dart-lang/language#2020 for details).

Fixes flutter/flutter#109339.
@flutter-dashboard
Copy link

It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption to this rule, contact Hixie on the #hackers channel in Chat (don't just cc him here, he won't see it! He's on Discord!).

If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix?

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.


final Object? _instanceToken;
/// Expando mapping instances of PlatformInterface to their associated tokens.
/// The reason we don't simply use a private field of type `Object?` is
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: could you adjust this comment (here and below) to remove the use of "we"? I can't actually tell who "we" is in this context (see go/avoidwe).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Contributor

@stuartmorgan-g stuartmorgan-g left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Just some minor comments on the explanation comment.

/// Expando mapping instances of PlatformInterface to their associated tokens.
/// The reason we don't simply use a private field of type `Object?` is
/// because as part of implementing
/// https://github.com/dart-lang/language/issues/2020, it will soon become a
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment will outlive the work, so referring to "soon" will soon be confusing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@stereotype441
Copy link
Contributor Author

@stuartmorgan, given that this change only affects the behavior of some corner cases in tests, I'm unsure whether I need:

  • a CHANGELOG entry
  • a version bump
  • tests

What do you think?

@stuartmorgan-g
Copy link
Contributor

@stuartmorgan, given that this change only affects the behavior of some corner cases in tests, I'm unsure whether I need:

  • a CHANGELOG entry
  • a version bump

It's changing production code (and will actually change behavior for clients), so needs both.

  • tests

Since we already have tests that would break later without this change, I think it's covered; I would ping Hixie for an exemption on this.

@stereotype441
Copy link
Contributor Author

@stuartmorgan, given that this change only affects the behavior of some corner cases in tests, I'm unsure whether I need:

  • a CHANGELOG entry
  • a version bump

It's changing production code (and will actually change behavior for clients), so needs both.

  • tests

Since we already have tests that would break later without this change, I think it's covered; I would ping Hixie for an exemption on this.

Thanks! I've added a CHANGELOG entry and bumped the version; I'll ping Hixie now.

@Hixie
Copy link
Contributor

Hixie commented Sep 12, 2022

Do we know of anyone who uses implements? Can't we just have them switch to extends instead? Expando logic is hard to understand and keeping the code simple seems very preferable unless the cost of migrating people is disproportionally large.

@stuartmorgan-g
Copy link
Contributor

stuartmorgan-g commented Sep 12, 2022

Do we know of anyone who uses implements? Can't we just have them switch to extends instead?

The point of this logic is to enforce that people don't make implementations of platform interfaces of federated plugins that use implements, because if they do it causes serious problems. As happened with webview, for instance, which predated this logic and was never updated to use it, so the mistake wasn't caught until it was too late (which is the cause of all of those PRs that are blocked in flutter/plugins that you keep finding in stale issue triage).

Expando logic is hard to understand and keeping the code simple seems very preferable unless the cost of migrating people is disproportionally large.

This allows us to throw a controlled error that matches our docs and has clear actionable instructions, instead of throwing something different in different cases for subtle language implementation reasons. I think having code that almost nobody ever needs to interact with be more complex is a reasonable tradeoff here in order to have a stable, actionable error for the many, many potential clients of this logic.

@Hixie
Copy link
Contributor

Hixie commented Sep 14, 2022

Ah, that was not clear from the original commit message or changelog entry. I definitely support the goal here. I just wish there was a cleaner (read, less Expando-magical way) to do it...

@Hixie
Copy link
Contributor

Hixie commented Sep 14, 2022

I think this is worth testing, FWIW. Verifying that we give good clear error messages for things like this is valuable.

@stereotype441
Copy link
Contributor Author

I think this is worth testing, FWIW. Verifying that we give good clear error messages for things like this is valuable.

Test added!

Copy link
Contributor

@stuartmorgan-g stuartmorgan-g left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM; one optional test change.

@stereotype441 stereotype441 merged commit feed66b into flutter:main Sep 15, 2022
@stereotype441 stereotype441 deleted the b-2020-61 branch September 15, 2022 16:53
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Sep 16, 2022
adam-harwood pushed a commit to adam-harwood/flutter_plugins that referenced this pull request Nov 3, 2022
… to an expando. (flutter#6411)

This change replaces `PlatformInterface._instanceToken` (an instance
field that points from a `PlatformInterface` to its corresponding
token) with an expando that maps from `PlatformInterface` to `Object`.
There is no change to the public API, and no change to the behavior of
users' production code.

This change ensures that if a customer tries to implement
`PlatformInterface` using `implements` rather than `extends`, the code
in `PlatformInterface._verify` won't try to access the private
`_instanceToken` field in `PlatformInterface`.  This is important
because an upcoming change to the dart language is going to cause such
accesses to throw exceptions rather than deferring to `noSuchMethod`
(see dart-lang/language#2020 for details).

Fixes flutter/flutter#109339.
mauricioluz pushed a commit to mauricioluz/plugins that referenced this pull request Jan 26, 2023
… to an expando. (flutter#6411)

This change replaces `PlatformInterface._instanceToken` (an instance
field that points from a `PlatformInterface` to its corresponding
token) with an expando that maps from `PlatformInterface` to `Object`.
There is no change to the public API, and no change to the behavior of
users' production code.

This change ensures that if a customer tries to implement
`PlatformInterface` using `implements` rather than `extends`, the code
in `PlatformInterface._verify` won't try to access the private
`_instanceToken` field in `PlatformInterface`.  This is important
because an upcoming change to the dart language is going to cause such
accesses to throw exceptions rather than deferring to `noSuchMethod`
(see dart-lang/language#2020 for details).

Fixes flutter/flutter#109339.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PlatformInterface._instanceToken needs reworking due to an upcoming dart language change

3 participants