Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: extend use_build_context_synchronously to consider Riverpod's WidgetRef #58744

Open
rrousselGit opened this issue May 20, 2022 · 10 comments
Labels
analyzer-linter Issues with the analyzer's support for the linter package area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. linter-lint-proposal linter-set-flutter linter-status-pending P3 A lower priority bug or feature request type-enhancement A request for a change that isn't a bug

Comments

@rrousselGit
Copy link

Hello! I'm not sure whether this is reasonable, but it's worth asking.

Long story short, Riverpod would like to define a lint strictly identical to use_build_context_synchronously but for its WidgetRef object.

The lint would be identical in every point, such that BuildContext/WidgetRef can constantly be interchanged. As a matter of fact, WidgetRef is a BuildContext. It uses a different interface to cause less confusion and allows folks using package:provider to smoothly migrate to package:riverpod.

As such, would it be reasonable to update use_build_context_synchronously to handle Riverpod's WidgetRef too?

Such that we have:

void fn() async {
  WidgetRef ref;

  await something;
  ref.anything();
  ^^^^^^^^^^ use_build_context_synchronously

  if (mounted) {
    ref.anything(); // ok
  }

I understand that this repository probably wants to be clean of third-party package logic.

If necessary, maybe a solution could be to add a custom package:meta annotation that both WidgetRef and BuildContext would use (@shouldUseSynchronously or @isBuildContext?)

@bwilkerson
Copy link
Member

The current rule says

When a BuildContext is used from a StatefulWidget, the mounted property must be checked after an asynchronous gap.

Does the same apply for WidgetRef, or would we need some way for the annotation to specify a property that can be checked?

@rrousselGit
Copy link
Author

Yes, this applies to WidgetRef too.

@rrousselGit
Copy link
Author

rrousselGit commented May 20, 2022

It's probably worth noting that WidgetRef is a class that interacts with BuildContext (hence why the rules should be respected)

Such that we have:

abstract class WidgetRef {
  void doSomething() {
    Object.of(context).doSomething();
  }
}

So maybe what makes sense would be to annotate the functions of WidgetRef, not WidgetRef itself. Maybe something like @useBuildContext?

abstract class WidgetRef {
  @useBuildContext
  void doSomething();
}

@bwilkerson
Copy link
Member

Definitely worth considering.

Would this be useful for other users? I don't know Flutter well enough to know whether users might write methods similar to doSomething or whether that's unlikely to occur very often.

@rrousselGit
Copy link
Author

It's probably not very common. Most cases would end-up passing the context variable as parameter to their function

The case described here is different because it already has access to the context, so passing it is redundant

@srawlins
Copy link
Member

srawlins commented Jan 3, 2023

CC @goderbauer any strong opinion?

@rrousselGit
Copy link
Author

For what it's worth, I'm working on riverpod-specific lint-rules using analyzer_plugin

So I could implement this on my own if necessary. Although the annotation approach here would make my like a lot easier

@navaronbracke
Copy link

navaronbracke commented May 15, 2023

@rrousselGit Another use case would be the mounted property on StateNotifier.

@bwilkerson Perhaps we can generalize the rule to a bool get mounted property regardless of the class?
I.e. if the class has such a property (I assume that we hard-reference to the name mounted here) and we don't add a return after an await, we flag the block of code?

class Foo {
 bool get mounted => true;
 
 void qux() {}
 
 void bar() async {
   await Future.delayed(const Duration(seconds: 1));
   
   if(!mounted) { // LINT without this check
     return;
   }
   
   qux();
 }
}

@bwilkerson
Copy link
Member

I'd like to get some input from the Flutter team before making a decision, but I'd much rather see us define an annotation that can be used outside of Flutter rather than implement some special case logic.

@navaronbracke
Copy link

I agree, having the use_build_context_synchronously lint is good in a Flutter context, but the idea behind it (not using some state that might have become invalid after an async gap) should be the focus of the lint imo.

@pq pq added the P3 A lower priority bug or feature request label May 22, 2023
@srawlins srawlins added the type-enhancement A request for a change that isn't a bug label Mar 27, 2024
@devoncarew devoncarew added analyzer-linter Issues with the analyzer's support for the linter package area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. labels Nov 19, 2024
@devoncarew devoncarew transferred this issue from dart-lang/linter Nov 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
analyzer-linter Issues with the analyzer's support for the linter package area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. linter-lint-proposal linter-set-flutter linter-status-pending P3 A lower priority bug or feature request type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

6 participants