Skip to content

Conversation

@a14n
Copy link
Contributor

@a14n a14n commented Nov 5, 2019

Description

Several methods in BuildContext were using Type to search for ancestor.

  • inheritFromWidgetOfExactType
  • ancestorInheritedElementForWidgetOfExactType
  • ancestorWidgetOfExactType
  • ancestorStateOfType
  • rootAncestorStateOfType
  • ancestorRenderObjectOfType

Most of those methods implied a cast at call site because their return type was a parent type. Moreover the type provided was not checked at analysis time even if the type is actually constrainted.

Making those methods generics improves type safety and need less code.

// before
ComplexLayoutState state = context.ancestorStateOfType(const TypeMatcher<ComplexLayoutState>()) as ComplexLayoutState;
// after
ComplexLayoutState state = context.ancestorStateOfType<ComplexLayoutState>();

Related Issues

None

Tests

None because it's a refactoring.

Checklist

Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes ([x]). This will ensure a smooth and quick review process.

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I signed the CLA.
  • I read and followed the Flutter Style Guide, including Features we expect every widget to implement.
  • I updated/added relevant documentation (doc comments with ///).
  • All existing and new tests are passing.
  • The analyzer (flutter analyze --flutter-repo) does not report any problems on my PR.
  • I am willing to follow-up on review comments in a timely manner.

Breaking Change

Does your PR require Flutter developers to manually update their apps to accommodate your change?

  • Yes, this is a breaking change (Please read Handling breaking changes). Replace this with a link to the e-mail where you asked for input on this proposed change.
  • No, this is not a breaking change.

@fluttergithubbot fluttergithubbot added d: examples Sample code and demos f: cupertino flutter/packages/flutter/cupertino repository f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels. c: contributor-productivity Team-specific productivity, code health, technical debt. customer: gallery Relating to flutter/gallery repository. Please transfer non-framework issues there. labels Nov 5, 2019
@a14n a14n removed d: examples Sample code and demos f: cupertino flutter/packages/flutter/cupertino repository f: material design flutter/packages/flutter/material repository. customer: gallery Relating to flutter/gallery repository. Please transfer non-framework issues there. labels Nov 5, 2019
@fluttergithubbot fluttergithubbot added d: examples Sample code and demos f: cupertino flutter/packages/flutter/cupertino repository f: material design flutter/packages/flutter/material repository. customer: gallery Relating to flutter/gallery repository. Please transfer non-framework issues there. labels Nov 6, 2019
@goderbauer
Copy link
Member

goderbauer commented Nov 6, 2019

I really like this clean-up and the extra type safety it gives us. However, this looks like a rather big breaking change that will also break many users of flutter (see current cirrus failures as an example). I wonder if we can somehow do this change with a softer transition where we deprecate the existing API, but it continuous to work until our dependencies had a chance to upgrade to the new API.

@a14n
Copy link
Contributor Author

a14n commented Nov 6, 2019

I really like this clean-up and the extra type safety it gives us.

Me too :)

this looks like a rather big breaking change that will also break many users of flutter

Yes :( but the upcoming NNBD will be way more breaking.

see current cirrus failures as an example

I planned to update scoped_model but I was wondering how to deal with that (flutter repo depends on scoped_model and scoped_model depends on flutter - perhaps make a git ref dependency on a fork of scoped_model until a new flutter version is out)

I wonder if we can somehow do this change with a softer transition where we deprecate the existing API, but it continuous to work until our dependencies had a chance to upgrade to the new API.

I thought about it and I didn't see a good solution:

  • make Type parameter optional could break overrides and is not possible with inheritFromWidgetOfExactType that already have an optional named parameter.
  • duplicate methods needs to have new method names (the current method names are good IMO) and deprecates old methods

I don't really know how often those methods are used outside of flutter but if someone has access to a corpus of code on pub it could be really interesting to grab some datas on the usage of those methods.

WDYT?

@a14n a14n force-pushed the generics-buildcontext branch 2 times, most recently from e4233e8 to d1fcbba Compare November 7, 2019 14:16
@a14n
Copy link
Contributor Author

a14n commented Nov 7, 2019

It's now green with a patched version of scoped_model.

@goderbauer goderbauer removed f: cupertino flutter/packages/flutter/cupertino repository f: material design flutter/packages/flutter/material repository. labels Nov 12, 2019
@Hixie
Copy link
Contributor

Hixie commented Nov 12, 2019

Can we make this less breaking by deprecating these versions and instead adding new methods with different (more uniform?) names that use the new style?

e.g. we could add "find" to those that are O(N), to make it clearer that they're more expensive.

I'm not sure exactly what to do with the O(1) ones...

Old New
inheritFromWidgetOfExactType ?
ancestorInheritedElementForWidgetOfExactType ?
ancestorWidgetOfExactType findAncestorWidgetOfExactType
ancestorStateOfType findAncestorStateOfType
rootAncestorStateOfType findRootAncestorStateOfType
ancestorRenderObjectOfType findAncestorRenderObjectOfType

@goderbauer
Copy link
Member

goderbauer commented Nov 12, 2019

I like the suggestion regarding the "find".

Here are my suggestions for the other two. I am hoping that "depend" makes it more clearer than "inherit" that you're adding a dependency on the InheritedWidget and get rebuilt whenever it changes. The other method's name just adopted to that naming scheme and the "get" sets it apart from the "find" in terms of lookup performance.

inheritFromWidgetOfExactType -> dependOnInheritedWidgetOfExactType
ancestorInheritedElementForWidgetOfExactType -> getElementForInheritedWidgetOfExactType

@a14n
Copy link
Contributor Author

a14n commented Nov 12, 2019

find* looks good to me.

Let me know what the other 2 methods should become.

@a14n a14n force-pushed the generics-buildcontext branch from d1fcbba to 5f2b8ca Compare November 12, 2019 21:03
@Hixie
Copy link
Contributor

Hixie commented Nov 12, 2019

@goderbauer's proposals LGTM.

Copy link
Member

Choose a reason for hiding this comment

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

nit: add a . add the end.

Copy link
Member

Choose a reason for hiding this comment

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

Here and elsewhere.

Copy link
Member

Choose a reason for hiding this comment

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

Also: insead -> instead.

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
Member

Choose a reason for hiding this comment

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

Also: The doc comment for this method should just say that this method is deprecated and point to the new method (no need to duplicate the doc comment).

Copy link
Member

Choose a reason for hiding this comment

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

Here and elsewhere.

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.

The doc comment for this method should just say that this method is deprecated and point to the new method (no need to duplicate the doc comment).

I only left the first sentence.

Copy link
Member

Choose a reason for hiding this comment

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

Name this getElementForInheritedWidgetOfExactType (I edited my suggestion shortly after posting, sorry if you only saw the old comment)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Renamed.

Copy link
Member

Choose a reason for hiding this comment

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

We should probably mark TypeMatcher as deprecated as well since that will go away as soon as we delete the old deprecated API?

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
Member

Choose a reason for hiding this comment

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

Can we implement the old API by calling the new API to avoid duplication?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Unfortunately not in this direction (the new can be implemented with the old) because we cannot extract T from Type.

Copy link
Member

Choose a reason for hiding this comment

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

Can you add a comment explaining why this is commented out?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I shouldn't have checked that in. Removed.

@goderbauer
Copy link
Member

I believe you may have to pull in the latest master to turn the tests green.

@a14n a14n force-pushed the generics-buildcontext branch from 5f2b8ca to 3477b1f Compare November 13, 2019 06:52
@a14n a14n force-pushed the generics-buildcontext branch from 7f3df90 to e30a4fd Compare November 15, 2019 08:43
@a14n
Copy link
Contributor Author

a14n commented Nov 15, 2019

@rrousselGit thanks for your suggestions. I'll let @Hixie and @goderbauer comment on them (all the prefixes look good to me except get*)

@goderbauer
Copy link
Member

Copy link
Member

@goderbauer goderbauer left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Member

Choose a reason for hiding this comment

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

It looks like for this test it wouldn't matter, so I would prefer the simplified version.

@goderbauer
Copy link
Member

(PR triage): @a14n Is this one good to go?

@a14n
Copy link
Contributor Author

a14n commented Nov 21, 2019

Is this one good to go?

Yes. I'm only waiting for a green tree.

@fluttergithubbot
Copy link
Contributor

This pull request is not suitable for automatic merging in its current state.

  • Please resolve merge conflicts before re-applying this label.

@a14n a14n merged commit fcb40a0 into flutter:master Nov 22, 2019
@a14n a14n deleted the generics-buildcontext branch November 22, 2019 16:35
mono0926 added a commit to mono0926/inherited_widget_explanation that referenced this pull request Dec 15, 2019
@Piinks Piinks mentioned this pull request Jan 11, 2021
9 tasks
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 3, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

c: API break Backwards-incompatible API changes c: contributor-productivity Team-specific productivity, code health, technical debt. customer: gallery Relating to flutter/gallery repository. Please transfer non-framework issues there. d: examples Sample code and demos framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants