Skip to content

cascade_invocations: Turning successive method invocations into cascading has sometimes unexpected behavior change #57631

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

Open
yyoon opened this issue Oct 3, 2017 · 3 comments
Labels
area-devexp For issues related to the analysis server, IDE support, linter, `dart fix`, and diagnostic messages. devexp-linter Issues with the analyzer's support for the linter package linter-false-positive P3 A lower priority bug or feature request type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)

Comments

@yyoon
Copy link
Contributor

yyoon commented Oct 3, 2017

This is related to the cascade_invocations rule.

We recently did a massive refactoring to address the cascade_invocations warnings, and found that one of those changes introduced a bug in our code.

class Foo {
  Bar _bar;

  Foo() {
    _bar = new Bar();
    _bar.addListener(_handleEvent);
    _bar.doSomething();    // This notifies all listeners
  }

  void _handleEvent() {
    // Use _bar variable here...
  }
}

The doSomething() call changes some internal states and then notifies all the listeners, and that includes the _handleEvent() method. This _handleEvent() implementation then reads the internal state of Bar, so it is important that _bar is correctly assigned before this happens.

We changed this to use cascading style instead.

  Foo() {
    _bar = new Bar()
      ..addListener(_handleEvent)
      ..doSomething();
  }

and it started to crash, because _bar is not yet assigned when _handleEvent() is called for the first time due to the doSomething() call.

We fixed this on our side once we found the issue, but it wasn't an obvious problem to find. I would think it would be difficult for the linter to determine whether it is safe to use cascade or not, but just wanted to call this out as a problem. Also related to #57626, as it's also about the order between the assignment and the method calls on that object.

@apwilson
Copy link
Contributor

apwilson commented Oct 5, 2017

I usually have this problem if I'm passing a function/closure to the thing I'm cascading that references the variable being set due to the cascade:

For instance:

Object _foo;

void bar() {
  _foo = new Foo()..addListener(_useFoo);
}
void _useFoo() {
  _foo.use();
}

In the above, if Foo.addListener calls the function _useFoo then _foo is unexpectedly null.

Doing this is more right in this case:

Object _foo;

void bar() {
  _foo = new Foo();
  _foo.addListener(_useFoo);
}
void _useFoo() {
  _foo.use();
}

@srawlins srawlins changed the title Turning successive method invocations into cascading has sometimes unexpected behavior change cascade_invocations: Turning successive method invocations into cascading has sometimes unexpected behavior change Jun 17, 2021
@srawlins
Copy link
Member

I don't think we could meaningfully catch these cases without overcatching by a lot. Tricky situation.

@srawlins
Copy link
Member

srawlins commented Sep 3, 2022

On second thought, I think we could catch when the cascade is part of an assignment, and the assignee is a field. (It's valid for when the assignee is a variable too, but less common?)

@srawlins srawlins added the P3 A lower priority bug or feature request label Oct 11, 2022
@srawlins srawlins added the type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) label Mar 29, 2024
@devoncarew devoncarew added devexp-linter Issues with the analyzer's support for the linter package legacy-area-analyzer Use area-devexp instead. labels Nov 18, 2024
@devoncarew devoncarew transferred this issue from dart-archive/linter Nov 18, 2024
@bwilkerson bwilkerson added area-devexp For issues related to the analysis server, IDE support, linter, `dart fix`, and diagnostic messages. and removed legacy-area-analyzer Use area-devexp instead. labels Feb 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-devexp For issues related to the analysis server, IDE support, linter, `dart fix`, and diagnostic messages. devexp-linter Issues with the analyzer's support for the linter package linter-false-positive P3 A lower priority bug or feature request type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)
Projects
None yet
Development

No branches or pull requests

5 participants