join-return-with-assignment
Same as join_return_with_assignment in Dart lints
- Group
- Complexity
- Path
lint/complexity/join-return-with-assignment- Default
- Off, opt in
- Origin
- Dart lints
- Rule
- 249 of 512
Flags an assignment immediately followed by return of the same variable.
When a block ends with x = e; return x; the two statements can be joined
into return x = e; (or simply return e; for a local). The rule looks at
the last two statements of every block: the second-to-last must be an
assignment (any operator), increment, decrement, or other prefix/postfix
expression on the same variable or property chain that the final return
yields. A run of assignments to that same target (x = a; x += b; return x;) is left alone, as are switch-case statement lists, which are not blocks.
Diagnostics cover the expression statement, including its semicolon.
int f(int a) {
a += 1; // flagged
return a;
}
Invalid
class A {
int _a = 0;
int b = 0;
late A next;
int incrementA() {
_a++;
return _a;
}
int plusEquals(int value) {
_a += value;
return _a;
}
int assignB(int value) {
b = value;
return b;
}
int? chained(A other) {
other.b = 3;
return other.b;
}
int? propertyChain(A other) {
print('x');
other.next.b = 4;
return other.next.b;
}
}
int prefix(int x) {
++x;
return x;
}
int afterOtherStatement(int x, int y) {
y = 2;
x = y + 1;
return x;
}
int nested(bool c, int x) {
if (c) {
x *= 2;
return x;
}
return 0;
}
int? nullable(int? x) {
x ??= 1;
return x;
}
int Function() closure(int x) {
return () {
x--;
return x;
};
}
// Parentheses around the returned name do not matter.
int parenthesizedReturn(int x) {
x = 1;
return (x);
}
class StateBase {
int get state => 0;
set state(int value) {}
}
class InheritedState extends StateBase {}
int pairedAccessors(InheritedState notifier) {
notifier.state = 1;
return notifier.state;
}
int pairedAccessorChain(List<InheritedState> notifiers) {
notifiers.first.state = 1;
return notifiers.first.state;
}
dynamic unresolvedMembers(dynamic receiver) {
// Unresolved dynamic properties have the same null canonical element in Dart.
receiver.first = 1;
return receiver.second;
} int incrementA() { _a++; int plusEquals(int value) { _a += value; int assignB(int value) { b = value; int? chained(A other) { other.b = 3; print('x'); other.next.b = 4;int prefix(int x) { ++x; y = 2; x = y + 1; if (c) { x *= 2;int? nullable(int? x) { x ??= 1; return () { x--;int parenthesizedReturn(int x) { x = 1;int pairedAccessors(InheritedState notifier) { notifier.state = 1; // Unresolved dynamic properties have the same null canonical element in Dart. receiver.first = 1;Valid
class A {
int _a = 0;
int b = 0;
A? next;
int joined() {
return ++_a;
}
// `this.b` is not an identifier chain, matching the analyzer.
int viaThis(int value) {
this.b = value;
return this.b;
}
// Mixing `b` and `this.b` is not provably the same element.
int mixed(int value) {
b = value;
return this.b;
}
int? nullAsserted(A other) {
other.next!.b = 4;
return other.next!.b;
}
}
// A preceding assignment to the same variable keeps the pair apart.
int runOfAssignments(int x) {
x = 1;
x += 2;
return x;
}
int differentVariable(int x, int y) {
x = 2;
return y;
}
int notLast(int x) {
x = 1;
print(x);
return x;
}
int indexed(List<int> list) {
list[0] = 1;
return list[0];
}
void noValue(int x) {
x = 1;
return;
}
// Switch-case statement lists are not blocks.
int inSwitch(int kind, int x) {
switch (kind) {
case 1:
x = 3;
return x;
default:
return 0;
}
}
int callStatement(List<int> list) {
list.add(1);
return list.length;
}
class StateBase {
int get state => 0;
set state(int value) {}
}
class ReadOverride extends StateBase {
@override
int get state => super.state;
}
// The getter and setter canonicalize to variables on different declarations.
int splitAccessors(ReadOverride notifier) {
notifier.state = 1;
return notifier.state;
}
int splitAccessorChain(List<ReadOverride> notifiers) {
notifiers.first.state = 1;
return notifiers.first.state;
}
int differentReceivers(StateBase first, StateBase second) {
first.state = 1;
return second.state;
}
int differentAccessSyntax(StateBase notifier) {
notifier.state = 1;
return (notifier).state;
}Configure join-return-with-assignment
Set its severity in falcon.json. See the configuration guide.
{
"linter": {
"rules": {
"complexity": {
"join-return-with-assignment": "error"
}
}
}
}Or silence one occurrence with a suppression comment; the reason is required.
// falcon-ignore lint/complexity/join-return-with-assignment: <reason>More complexity rules
- max-lines-for-file
max_lines_for_fileFlags a file longer than the configured line limit.
- max-lines-for-function
max_lines_for_functionFlags a function or method longer than the configured line limit.
- max-parameters-for-function
max_parameters_for_functionFlags callable declarations and function types with more than the configured number of parameters.
- max-statements
Reports function bodies with too many statements.
- max-switch-cases
max_switch_casesFlags a
switchstatement with more than the configured number of cases. - maximum-nesting-level
maximum_nesting_levelFlags a function whose control-flow nesting runs deeper than the configured level.
- no-boolean-literal-compare
no-boolean-literal-comparerecommendedDon't compare boolean values to boolean literals.
- one-member-abstracts
one_member_abstractsFlags abstract classes whose only member is a single abstract method.